Git Product home page Git Product logo

hedis's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

hedis's Issues

Cannot install Hedis on Windows

Hello,

When I try to install hedis on Windows 10 I see the build failing with this message :

Not in scope: data constructor UnixSocket' Perhaps you meant variable NS.bindSocket' (imported from Network.Socket)

Roelof

Don't allow sending empty lists

In most APIs, it's an error to send an empty list as an argument. For example:

sadd "test-set" []

This will give you an error. Need to think to either switch to NonEmpty type or to skip empty lists somehow. Skipping is problematic since current API is exposing too much to a user, it returns a type corresponding to a redis-response, while I think it would be more logical to only return a success response, throwing exception (or skipping error) in other case.

Disconnect/destroy the connection pool

Hi

Is there a way to explicitly disconnect the Connection (Pool)?

Neither the Pool (hidden by the newtype constructor Conn) nor the disconnect / destroy functions are exposed.

Thanks

_Scan?

Is any of the scan commands implemented?

Are there any plans to do this?

Please add support for bytestring-lexing-0.5.x

We would like to distribute hedis-0.6.5 in NixOS, but our attempts to build it currently fail because we've updated to bytestring-lexing-0.5.x already, which the build doesn't support.

Exception handling question

Hedis exports only 1 exception, but it seems to me that is unfortunately quite unwelcome. The problem is that thanks to unsafeInterleaveIO the exception can occur anywhere. Which would still be somewhat managable in the IO monad, but I need to use it on top of a transformer stack and catching IO exceptions there is really tricky. I ended up threading all calls through evaluate but that defies the purpose of optimal pipelining. (given the workflow I have no benefit from that anyway).

Throwing exceptions 'anywhere' doesn't seem to me a good design. Is there a way to not throw the exceptions? I.e. catch the exceptions somewhere during the communication and return Left/TxError instead? This would be nice haskellish design decision anyway.

thread blocked indefinitely in an MVar operation

Please consider the following test case:

{-# LANGUAGE OverloadedStrings #-}

module Main where

import Control.Monad
import Database.Redis

main :: IO ()
main = do
    r <- connect defaultConnectInfo { connectPort = PortNumber 9042 }
    void $ runRedis r $
        replicateM 2000 $ do
            x <- expire "hello" 10
            return x

Execution yields (potentially after multiple runs):

$ ghc --make -O2 -threaded -Wall -fforce-recomp testcase
[1 of 1] Compiling Main             ( testcase.hs, testcase.o )
Linking testcase ...
$ ./testcase 
testcase: ConnectionLost
testcase: thread blocked indefinitely in an MVar operation

The ConnectionLost exception was provoked by the fact that there isn't actually a Redis server listening on port 9042 but a different service (Cassandra). The test case is setup this way to highlight two aspects:

  1. All parsing failures are interpreted as connection loss.
  2. If the evaluation thread gets to evaluate errConnClosed it is terminated immediately, i.e. there is no longer a consumer of the bounded channel connThunks.

The second point in turn leads to the BlockedIndefinitelyOnMVar exception if the bounded channel becomes full. This can happen if the results of recv calls are not evaluated fast enough within runRedis. If we change the test case to force evaluation to HNF we get instead:

{-# LANGUAGE OverloadedStrings #-}

module Main where

import Control.Monad
import Database.Redis

main :: IO ()
main = do
    r <- connect defaultConnectInfo { connectPort = PortNumber 9042 }
    void $ runRedis r $
        replicateM 2000 $ do
            x <- expire "hello" 10
            x `seq` return x
$ ghc --make -O2 -threaded -Wall -fforce-recomp testcase
[1 of 1] Compiling Main             ( testcase.hs, testcase.o )
Linking testcase ...
$ ./testcase 
testcase: ConnectionLost
testcase: ConnectionLost

Forcing the evaluation evaluates errConnClosed (= throwIO ConnectionLost) within runRedis immediately which then guarantees that the connection is closed and the evaluation thread killed.

That being said it seems that using seq would destroy the pipelining property so maybe instead the evaluation thread should catch exceptions to guarantee there is always a consumer of connThunks as long as the connection is in use?

hackage

Can you expose this cool thing on hackage?

Can' build

Build fails:

Types.hs:90:10:
    Illegal instance declaration for `RedisReturnStatus String'
      (All instance types must be of the form (T t1 ... tn)
       where T is not a synonym.
       Use -XTypeSynonymInstances if you want to disable this.)
    In the instance declaration for `RedisReturnStatus String'

I'm not going to send a pull request - one string

PubSub: do not depend on messages arriving in order to get control

Hedis' PubSub interface is really neat, making sure you can never exit without having unsubscribed to all the channels. Unfortunately (unless I missed something) you can never gain control unless a message arrives. A situation is the following: you subscribe to a channel, exchange with redis, and at some point want to unsubscribe; unfortunately you have to wait until the next message arrives in order for your code to be executed. This is clear from the type signature:

pubSub
    :: PubSub                 -- ^ Initial subscriptions.
    -> (Message -> IO PubSub) -- ^ Callback function.
    -> Core.Redis ()

You could prevent your callback from returning, but it's not particularly elegant, and you'd miss all the further incoming messages (really not an option).

The interface is actually really nice, but I think it could somehow be made more powerful. It's annoying to have to use "bare metal" commands from Core with in order to gain more flexibility. I don't have a solution for this, but it's probably worth thinking about. pubSub could look more like runRedis, except that it will lock you in if you are still subscribed to any channel, and will prevent you from running any non-pubsub command.

That is, there could be a PubSub monad (just a newtype wrapper Redis just allowing subscription/unsubscription) and pubSub would have type

pubSub 
    :: [Channel] -- ^ inital subscriptions
    -> PubSub a -- ^ action to run
    -> Either (PubSub a) (Core.Redis a)

so that in case you are not fully unsubscribed when returning (that is, if the result of the last command did not return a null number of subscriptions), it would return a Left (PubSub a) which you'll have to handle explicitly. This should also help with #28 since all requests can be handled explicitly before pubSub returns.

This is not as nice as the monoid interface, and probably not the best alternative, but I think it would work. Please let me know if I missed something very simple, and please share your thoughts in general. :)

Failed connection in transaction results in weird exceptions

Running a transaction (following code) results in exception showing that something is trying to access a closed handle. When I was trying it in my larger codebase it even seemed somewhat indeterministic (sometimes it failed before the threadDelay, sometimes after.

  {-# LANGUAGE OverloadedStrings #-}

  import Control.Concurrent (threadDelay)
  import Database.Redis
  import Control.Monad (void)
  import Control.Monad.IO.Class (liftIO)

  main :: IO ()
  main = do
    conn <- connect defaultConnectInfo
    void $ runRedis conn
      (multiExec $ do
        void $ set "testkey" "testval"
        liftIO $ threadDelay 10000000
        expire "testkey" 60
        )
    return ()

Pubsub and connection handling

I'm having issues with pubsub -- I can subscribe to channels and receive data just fine for short-term intervals, but after a while, stuff seems to just... stop arriving. Are subscriptions properly handled in the connection pool? Because it seems like the subscribe command is just executed on a connection in the pool and forgotten, and if that connection is lost and replaced with another in the pool, the subscription is also lost.

Generalized Constraints

The concrete IO types in hedis make it very hard to use with other kinds of Monads, especially in applications using Monad transformers. How do you feel about making more generalized types available? For example:

--- a/src/Database/Redis/Core.hs
+++ b/src/Database/Redis/Core.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE FlexibleContexts #-}
 {-# LANGUAGE OverloadedStrings, GeneralizedNewtypeDeriving, RecordWildCards,
     MultiParamTypeClasses, FunctionalDependencies, FlexibleInstances, CPP #-}
 
@@ -15,6 +16,7 @@ import Prelude
 import Control.Applicative
 #endif
 import Control.Monad.Reader
+import Control.Monad.Trans.Control
 import qualified Data.ByteString as B
 import Data.IORef
 import Data.Pool
@@ -62,7 +64,7 @@ instance MonadRedis Redis where
 --  Each call of 'runRedis' takes a network connection from the 'Connection'
 --  pool and runs the given 'Redis' action. Calls to 'runRedis' may thus block
 --  while all connections from the pool are in use.
-runRedis :: Connection -> Redis a -> IO a
+runRedis :: (MonadIO m, MonadBaseControl IO m) => Connection -> Redis a -> m a
 runRedis (Conn pool) redis =
   withResource pool $ \conn -> runRedisInternal conn redis
 
@@ -82,8 +84,8 @@ reRedis r = Redis r
 
 -- |Internal version of 'runRedis' that does not depend on the 'Connection'
 --  abstraction. Used to run the AUTH command when connecting.
-runRedisInternal :: PP.Connection -> Redis a -> IO a
-runRedisInternal conn (Redis redis) = do
+runRedisInternal :: MonadIO m => PP.Connection -> Redis a -> m a
+runRedisInternal conn (Redis redis) = liftIO $ do
   -- Dummy reply in case no request is sent.
   ref <- newIORef (SingleLine "nobody will ever see this")
   r <- runReaderT redis (Env conn ref)

In my particular application, I'm extremely interested in building Conduit Producers/Sources around pubSub and Consumers/Sinks around publish. With the current IO types, I've had to introduce a and thread queue for sourcing from / sinking to redis with hedis instead of a having more general Producers/Sources and Consumers/Sinks:

sinkBus :: MonadIO m => Connection -> TBQueue (ByteString, ByteString) -> m ()
sinkBus conn msgQueue =
  liftIO $ runRedis conn $
    forever $ do
      (channel, message) <- liftIO $ atomically $ readTBQueue msgQueue
      publish channel message

sourceBus :: MonadIO m => Connection -> TBQueue (ByteString, ByteString) -> [ByteString] -> m ()
sourceBus conn msgQueue channels =
  liftIO $ runRedis conn $
    pubSub (psubscribe channels) $ \msg -> do
      atomically $ writeTBQueue msgQueue (msgChannel msg, msgMessage msg)
      return mempty

In particular, having to introduce a thread and queue for reading from / writing to redis is particularly onerous in my application with significant thread counts already :(

/cc @snoyberg in case I'm misunderstanding the limitations here around conduits. I'm happy to help with generalizing the types if that's desirable. Thanks for the great library!

Force-close connection

Looks like QUIT only sends a "quit" request and connection is left to RTS to finish the procedures. This yields "Too many open files" errors when under highly-concurrent load. Is there a way to close connection right away?

Bug report: Double type (zrangeWithscores)

I found this bug while testing redis' sorted sets. The problem appeared when I wanted to add a value very close to 0. The following actions are done with redis-cli:

127.0.0.1:6379> ZADD test -0.000020221356243895889 PrPZck9bNdCcQ9qq3Ia
127.0.0.1:6379> ZRANGE test 0 -1 WITHSCORES
1) "PrPZck9bNdCcQ9qq3Ia"
2) "-2.0221356243895889e-05"

Now, if I want to use the "zrangeWithscores" function from "Database.Redis" on this sorted set, this happens:

runRedis conn $ zrangeWithscores "test" 0 (-1)
Right [("PrPZck9bNdCcQ9qq3Ia",-2.022135624389589)]

This is wrong, as it ignores the "e-05" part, which makes a big difference in this case.

I think the problem might be here: https://github.com/informatikr/hedis/blob/master/src/Database/Redis/Types.hs (lines 68-69).

instance RedisResult Double where
    decode r = maybe (Left r) (Right . fst) . F.readSigned F.readDecimal =<< decode r

as

$ ghci
λ> :set -XOverloadedStrings
λ> import qualified Data.ByteString.Lex.Fractional as F (readSigned, readDecimal)
λ> F.readSigned F.readDecimal $ "-2.0221356243895889e-05"
Just (-2.022135624389589,"e-05")

Enhancement request: TLS-over-TCP support

I am using a hosted/managed Redis instance within Azure, and by default, that must be accessed with TLS. Hedis works fine if I enable non-TLS connections to the Azure redis service, but I cannot do so without compromising my app's security (I need to communicate over the internet to redis).

Unfortunately I am just not knowledgeable enough to make this change to hedis myself. Please consider this as an enhancement request. Thank you!

Connecting to non-existing server doesn't fail until a request is made

If you try to connect to a redis instance that isn't running, the connect function does not complain. Only when you try to use the connection is an exception thrown (by the connectTo function from package Network). I really feel this should happen during the call to connect.

Easily reproducible in GHCI: (make sure redis-server is not running on your local machine)
> import Database.Redis
> conn <- connect defaultConnectInfo --no problem so far
> runRedis conn ping --throws exception "*** Exception: connect: does not exist (Connection refused)"

I'm not sure where the problem lies. At first I thought that laziness was the culprit, but since the usual tricks with seq didn't work for me I now suspect Data.Pool to be the culprit. I could easily be wrong though.

README links to wrong repo

diff --git i/README.md w/README.md
index d7b7df5..1003fbc 100644
--- i/README.md
+++ w/README.md
@@ -8,7 +8,7 @@ We are happy to receive bug reports, fixes, documentation enhancements, and othe

 Please report bugs via the [github issue tracker](http://github.com/informatikr/hedis/issues).

-Master [git repository](http://github.com/hedis/hedis):
+Master [git repository](http://github.com/informatikr/hedis):

     git clone git://github.com/informatikr/hedis.git

connect ignores AUTH and SELECT results

  • When a connection password is set in connectAuth, but the Redis instance does not require a password, the connection is created anyway.
  • When a database number is set in connectDatabase but the Redis instance does not have a database with that number, the connection is created anyway.

Both of these effects are probably by design. However, I believe they may be dangerous.

  • When a Redis instance is (wrongfully) configured not to require a password, you want to know about this, as this may be a security risk. This one is debatable, as redis-cli also continues when a password is set with -a but the server does not require one.
  • When the number of databases on a Redis instance is lowered and some component is still configured to use a database that does not exist anymore, it will start using database 0 without notice. This may cause it to overwrite data it should not touch.

What do you think? I don't mind writing a PR for this as long as it is desired.

PubSub can still receive mesages after unsubscribe

I would expect that once punsubscribe is invoked handler won't receive single message. In this example getmessages receives many more messages

{-# LANGUAGE OverloadedStrings #-}

import Control.Monad
import Control.Monad.Trans
import Data.Monoid
import Database.Redis
import Data.ByteString.Char8
import Control.Concurrent.Async

sendmessages n = do
    conn <- connect defaultConnectInfo
    runRedis conn $ do
        forM_ [1..n] $ \x -> publish "hello" (pack ( "num" ++ (show x) ) )

getmessages = do
    conn <- connect defaultConnectInfo
    let chan = ["hello"]
    runRedis conn $
        pubSub (psubscribe chan) $ \msg -> do
            Prelude.putStrLn $ "Message from " 
                              ++ unpack (msgChannel msg) 
                              ++ " " 
                              ++ unpack (msgMessage msg)
            return $ punsubscribe chan

testpubsub = do
    a1 <- async getmessages
    a2 <- async ( sendmessages 100000 )
    wait a1
    wait a2

main = testpubsub

Possible silently ignored exceptions

connHandle <- connectTo host port

"What if hSetBinaryMode in connect throws an exeption? Will the handle be closed? Probably GC will do close it eventually, but I can't check that, especially in presence of unsafeInterleaveIO.

What if hClose in disconnect thows? Will the connEvalTId thread be killed? Probably not."

Context: https://www.reddit.com/r/haskell/comments/3lxy9n/haskell_vs_scala_for_the_core_product/cvamejg

Hedis hangs on reading big zset

Here is a piece of code:

{-# LANGUAGE OverloadedStrings #-}

import Database.Redis
import System.Random
import qualified Data.ByteString.Char8 as BC8

main :: IO ()
main = do
  conn <- connect (defaultConnectInfo { connectHost="localhost" })

  stdGen <- getStdGen
  runRedis conn (fillBigZset stdGen 20000)

  resp <- runRedis conn $ zrangebyscoreLimit "bigzset" 0 1403194724 0 15000
  putStrLn $ "Response: " ++ show resp
  return ()

fillBigZset :: (RedisCtx m f, RandomGen t)
            => t -> Int -> m ()
fillBigZset _ 0 = return ()
fillBigZset gen n = do
    let (v, newGen) = randomR (1,1000000) gen
    _ <- zadd "bigzset" [(v, BC8.pack ("value-value-value-value-value-" ++ show v))]
    fillBigZset newGen (n - 1)

You can comment out 2 lines that fill redis after first time you run it. On my machine, this hangs with redis 2.6. Also tried with latest 2.8 one.

strace output: https://gist.github.com/k-bx/cd3cb178412ea9c50e71

0.3 Build fails

Hackage version:

src/Database/Redis/Connection.hs:129:43:
    Not in scope: `catchIOError'

Clarify Supported Versions of Redis

On the package description page for hedis, the following statement is present:

Complete Redis 2.6 command set

This leads me to believe that I should use redis 2.6 or higher (with the understanding that commands added after version 2.6 may not work). From the travis file, I can see that this library is being tested against 3.0.7. On redis's homepage, the notes for 3.2 currently read:

Redis 3.2 contains significant changes to the API and implementation of Redis.

As someone new to redis, I have a hard time deciding which version to use based on the available documentation. It would be nice to see a something on the package description that says something along the lines of: "hedis is supported for redis versions ...". For me, that would help speed up the process of getting started with the library.

More specific Error types

Currently for error conditions outside of transactions hedis returns a Left (Error ByteString :: Reply), which confuses me a little bit.

For example it was not immediately clear to me whether the error bytestring encodes only utf-8 strings. Further, it is only in the documentation where you can find that the Left reply will only ever contain an Error and not any of the SingleLine, Integer, Bulk or MultiBulk constructors.

Wouldn't it be possible to simplify those signatures to a more straight-forward Either Text a? Do I understand what's going on?

(PS attempting to quickly port https://github.com/scan/redissession from the deprecated redis to hedis)

Add benchmark

Could be cool to have a complete and clear benchmark (much like the one distributed with Redis itself) ! Criterion might allow us to do that easily.

stm dependency on hackage

Version 0.4 on hackage needs stm 2.3.. But a lot of other packages needs earlier versions. Can you relax constraint? The more so that the restriction in HEAD is 2.2..

FromJSON ToJSON instances for config

I am thinking maybe it's a good idea to have ready to go instances for json/yml/whateverml so that people would be able to use it in their apps and just put the configs into config/redis.yml or whatever?
There is a solution for that already: https://bitbucket.org/s9gf4ult/hedis-config. But, the problem with it is that it's outdated and doesn't compile with the latest hedis version.
I've created PRs to make it work with latest versions of hedis, but, the author didn't respond to me. So, I am thinking, maybe we could add this thingy right there?

Thunks leaking from sendRequest

I have a rather simple but long-running script which reads data (tens of gigabytes) from a file and produces Redis SADDs. I've found that memory usage in this program grows linearly in the run time. It seems that the source of the leak is sendRequest called from sadd and the objects leaked are thunks of type stg_sel_upd and stg_ap_2_upd_info. The attached test case demonstrates the problem. You will find that memory usage monotonically increases as execution proceeds.

Installation fails

cabal install hedis
Resolving dependencies...
Configuring resource-pool-0.2.3.2...
Building resource-pool-0.2.3.2...
Failed to install resource-pool-0.2.3.2
Build log ( /Users/valery/.cabal/logs/resource-pool-0.2.3.2.log ):
cabal: Entering directory '/var/folders/d_/l51rl27d1kv2h_y48v8522980000gn/T/cabal-tmp-19896/resource-pool-0.2.3.2'
Configuring resource-pool-0.2.3.2...
Building resource-pool-0.2.3.2...
Preprocessing library resource-pool-0.2.3.2...
: cannot satisfy -package-id hashable-1.2.5.0-D2qhjboTBST6rFOSUg03ZP
(use -v for more information)
cabal: Leaving directory '/var/folders/d_/l51rl27d1kv2h_y48v8522980000gn/T/cabal-tmp-19896/resource-pool-0.2.3.2'
cabal: Error: some packages failed to install:
hedis-0.9.8 depends on resource-pool-0.2.3.2 which failed to install.
resource-pool-0.2.3.2 failed during the building phase. The exception was:
ExitFailure 1

Redis Time-Series Module support

I would like to use the Redis Time-Series Module but it isn't supported by hedis. And I would argue, as I'm sure you would, that it shouldn't be supported by hedis.

Do you have any advice on how I would solve this problem? I was thinking that I could create a separate package that only supports that particular module but uses functions, internal to hedis, such as sendRequest. However I'm a newb and I'm not completely clear on whether that will work or not. Or maybe an alternative, more general, approach would be better?

Hedis returns escaped UTF8 escape sequences

I recently had the pleasure of using Hedis in a project I was working on (I can't say details about the project). It was a great, clean library that was an absolute pleasure to use, except in one area: encoding. At one point, I was BRPOPing some text with the character é. Surprisingly enough, Hedis spat out a response with some messed up encoding, opting to return a UTF8 encoded value.

Upon farther investigation, the UTF8 encoding was done in such a way that the escape sequences were escaped themselves. I did some digging (including running redis-cli in raw mode) and I discovered that Redis properly returns irregular characters like é. Furthermore, it is well known that Redis doesn't modify/encode/decode/whatever data it receives.

So I wrote my own stripped down Redis client using Network.Socket.ByteString, and sure enough (in addition to being ever so slightly faster :p) the é character was returned correctly (I wrote the result to a file using Data.Text.IO and Data.Text.Encoding and use the UNIX cat command to read it).

Would a possible solution be to use Network.Socket.ByteString in place of whatever is being used currently?

Pubsub and connectMaxIdleTime

Hey!

When using hedis for pub/sub, the connection to Redis supporting pubsub can be closed due to connectMaxIdleTime reached if there are other long running connections. In this case, it is not reopened automatically and we don't have any clue on why nothing is hapenning anymore.

Dunno what the best way to handle is. Maybe disable connectMaxIdleTime when a subscription is active for a given connection?

`liftRedis` of `MonadRedis` is exported but not `returnDecode` of `RedisCtx`

Is there a reason that liftRedis is exported but returnDecode is not. I ask because the export of liftRedis makes it look like it should be possible to create your own MonadRedis instance but you can't actually create a useful one since there is no way to create a RedisCtx instance.

Basically what I wanted to do is something like this in my code

instance (MonadIO m) => MonadRedis (ReaderT App m) where
  liftRedis m = do
    c <- connRedis <$> ask
    (liftIO . runRedis c) m

instance (MonadIO m) => RedisCtx (ReaderT App m) (Either Reply) where
  returnDecode = pure . decode

So the instance for RedisCtx does not compile because returnDecode is not exported.

This is really just a nice to have, but I would say that either liftRedis should not be exported or returnDecode should also be exported for consistency sake at least.

Transaction API is confusing

I recently answered a Stack Overflow question in which the questioneer was confused about the meaning and usage of the Queued type. I agree with them: the Queued type and the multi-parameter RedisCtx class do seem unintuitive.

In my answer, I argued that a monadic interface is not the right abstraction for Redis transaction batches. I also gave an outline of a simpler Applicative interface on top of RedisTx, which does away with the confusing elements of the current design:

newtype RedisBatch a = RedisBatch (R.RedisTx (R.Queued a))
-- being a transactional batch of commands to send to redis

instance Functor RedisBatch where
    fmap = liftA

instance Applicative RedisBatch where
    pure x = RedisBatch (pure (pure x))
    (RedisBatch rf) <*> (RedisBatch rx) = RedisBatch $ (<*>) <$> rf <*> rx

Is there an appetite for changing the hedis API to remove the Queued type and expose a purely-applicative interface for RedisTx? It'd be a breaking API change, and the work would likely involve changing the MonadRedis/RedisCtx hierarchy.

I'd be keen to make a pull request for this, but I wanted to gauge interest before I get started so as not to waste anyone's time.

Hedis hangs on value with > 4087 chars

Hey,
Just notice a very weird issue where hedis hangs on a large set.

main = do
    putStrLn "Starting redis check"
    conn <- R.connect R.defaultConnectInfo 
    s <- return $ (replicate 4087 'a')
    R.runRedis conn $ do
        liftIO $ putStrLn "Making req for test"
        val <- R.set (C.pack "test") (C.pack s)                                                                                                                                   
        liftIO $ putStrLn $ show val 
        R.get (C.pack "test")

works.
But the following doesn't:

main = do
    putStrLn "Starting redis check"
    conn <- R.connect R.defaultConnectInfo 
    s <- return $ (replicate 4088 'a')
    R.runRedis conn $ do
        liftIO $ putStrLn "Making req for test"
        val <- R.set (C.pack "test") (C.pack s)                                                                                                                                   
        liftIO $ putStrLn $ show val 
        R.get (C.pack "test")

And for any other value greater than that. Say 6000.
The get works on redis-cli

Is there a config param I'm missing or something?

Web browsable documentation for Database.Redis module not on hackage

Wanted to check out the public API for Database.Redis in browser, noticed I couldn't click the module to get that information in browser. I find this to be a pretty nice experience when evaluating a library / reference docs rather than scanning through a source file.

Please forgive any off terminology, still fairly new to the Haskell community / ecosystem.

Connection pool doesn't like blocking commands?

{-# LANGUAGE OverloadedStrings #-}
import Control.Concurrent
import qualified Data.ByteString.Char8 as B
import Database.Redis

main :: IO ()
main = do
    conn <- connect defaultConnectInfo { connectMaxConnections = 1024 }
    forkIO $ do 
        threadDelay 100000
        runRedis conn $ lpush "locktest" ["0"]
        return ()
    bar <- runRedis conn $ blpop ["locktest"] 0
    case bar of
        Left foobar -> putStrLn "Test!"
        Right barfoo -> putStrLn "Potato!"

The program hangs, although it doesn't for smaller values in threadDelay. I was assuming the behavior would be for it to pause 0.1 seconds for the LPUSH and then print out "Potato!" after the BLPUSH unblocks. Is this intended behavior?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.