informatikr / hedis Goto Github PK
View Code? Open in Web Editor NEWA Redis client library for Haskell.
Home Page: http://hackage.haskell.org/package/hedis
License: BSD 3-Clause "New" or "Revised" License
A Redis client library for Haskell.
Home Page: http://hackage.haskell.org/package/hedis
License: BSD 3-Clause "New" or "Revised" License
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
The link to Database.Redis on Hackage says there is no documentation for the module
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?
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?
These commands are missing.
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.
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. :)
Redis 2.8.9 added HyperLogLog support (see e.g. http://redis.io/commands/pfadd). It'd be nice if Hedis supported this.
I don't actually need this feature, just opening an issue about it because I'm interested in writing it.
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")
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.
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..
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
"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
Support for URL of the form: unix:///var/path/to/redis.sock?db=1
Example: https://github.com/singpolyma/ipfs-websub/blob/master/RedisURL.hs
If not, I'm going to build it and submit a pull since I need it...
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.
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.
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 ()
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.
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.
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
{-# 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?
Is any of the scan commands implemented?
Are there any plans to do this?
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
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.
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
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
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.
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.
Is it possible to add a timeout in subscribe
and psubscribe
? It would be very convenient for short-lived channels.
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!
The line below triggers a fail when trying to connect to a local Unix socket:
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
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.
Need to download and run them manually for non-sudo container env.
The hdel command (http://redis.io/commands/hdel) returns the number of deleted fields, so its result should be an integer. However, the hedis package defines hdel as returning a Bool.
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?
Hackage version:
src/Database/Redis/Connection.hs:129:43:
Not in scope: `catchIOError'
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
)
Can you expose this cool thing on hackage?
As of 2.6.12 there are a lot more options for SET.
I'm not sure how the best way to do this would be. I'm just going to hardcode a method in my project that does what I want.
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.
Since redis sentinel has made it into a release, I thought it would be a good idea to look into what it would take to add sentinel support for hedis:
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!
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:
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?
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?
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?
connectAuth
, but the Redis instance does not require a password, the connection is created anyway.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.
redis-cli
also continues when a password is set with -a
but the server does not require one.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.
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?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.