wooga / eredis Goto Github PK
View Code? Open in Web Editor NEWErlang Redis client
License: MIT License
Erlang Redis client
License: MIT License
I may do something wrong or maybe there are some prerequisites. I am running it on Erlang 18.3.
$ rebar -v eunit
==> eredis (eunit)
INFO: sh info:
cwd: ".../eredis"
cmd: cp -R src/basho_bench_driver_eredis.erl src/basho_bench_driver_erldis.erl src/eredis_client.erl src/eredis_sub_client.erl src/eredis_sub.erl src/eredis.erl src/eredis_parser.erl test/eredis_sub_tests.erl test/eredis_tests.erl test/eredis_parser_tests.erl ".eunit"
Compiled src/eredis_parser.erl
Compiled src/eredis.erl
Compiled src/basho_bench_driver_erldis.erl
Compiled src/basho_bench_driver_eredis.erl
Compiled src/eredis_sub.erl
Compiled src/eredis_client.erl
Compiled src/eredis_sub_client.erl
Compiled test/eredis_sub_tests.erl
Compiled test/eredis_tests.erl
Compiled test/eredis_parser_tests.erl
INFO: Cover compiling .../eredis
======================== EUnit ========================
module 'basho_bench_driver_erldis'
module 'eredis_sub_client'
module 'eredis_sub'
module 'eredis_sub_tests'
eredis_sub_tests: pubsub_test...*skipped*
undefined
*unexpected termination of test process*
::{connection_error,{connection_error,econnrefused}}
=======================================================
Failed: 0. Skipped: 0. Passed: 0.
One or more tests were cancelled.
Cover analysis: .../eredis/.eunit/index.html
ERROR: One or more eunit tests failed.
ERROR: eunit failed while processing .../eredis: rebar_abort
Hello there, I've been using eredis and it has worked perfect all this time.
I am using eredis through a small wrapper module to simplify calls and query patterns.
The next function wraps a query abstracting the conection to eredis:
redisq(Q) -> C = redis_conn(), {ok, V} = eredis:q(C, Q), eredis:stop(C), V.
This worked just fine until otp21. The data gets retrieved but now
the caller process gets exit messages with the form {'EXIT',<0.13696.0>,normal}
I had to modify the wrapper query function to this to avoid leaking messages:
redisq(Q) -> Parent = self(), Ref = make_ref(), spawn(fun() -> C = redis_conn(), {ok, V} = eredis:q(C, Q), eredis:stop(C), Parent ! {Ref, V} end), receive {Ref, V} -> V end.
Is it normal to receive that 'EXIT' messages or am I using eredis badly?
Hi,
I am reading the code in https://github.com/wooga/eredis/blob/master/src/eredis_client.erl#L257
There is an assumption that redis server will return response based on FIFO order of requests.
My set up is eredis is connected to a haproxy/twemproxy which connects to multiple redis servers, so multiple redis server can return data in different order.
Does it break your assumption? Will it still work?
Cheers,
Howard
Using a timeout of 60s like this
eredis:q(pid(0,17393,766), ["SMEMBERS", "access_64628"], 60000).
I still get a timeout after 5s. It looks to me as if another gen_server:call
is triggered internally with the default timeout.
** exception exit: {{timeout,{gen_server,call,
[<0.17393.766>,
{request,[[<<"*">>,"3",<<"\r\n">>],
[[<<"$">>,"4",<<"\r\n">>,<<"SADD">>,<<"\r\n">>],
[<<"$">>,"12",<<"\r\n">>,<<"access_64645">>,<<"\r\n">>],
[<<"$">>,"57",<<"\r\n">>,
<<"some data "...>>,
<<"\r\n">>]]]},
5000]}},
{gen_server,call,
[<0.17393.766>,
{request,[[<<"*">>,"2",<<"\r\n">>],
[[<<"$">>,"8",<<"\r\n">>,<<"SMEMBERS">>,<<"\r\n">>],
[<<"$">>,"12",<<"\r\n">>,<<"access_64628">>,<<"\r\n">>]]]},
60000]}}
Any pointers where to start looking for a fix?
Cheers,
Martin
Hi there,
I use eredis as client to store erlang server's log, and I don't care whether redis command executed success or failure, so is there any method like qp_noreply? For log storage, LPUSH+LTRIM is a common pipeline. thanks!
i setup eredis and do as wiki, the result is :
([email protected])3> eredis_sub:sub_example().
{ < 0.1536.0 >,< 0.1537.0 >}
received {subscribed,<<"foo">>,< 0.1536.0 >}
([email protected])4> eredis_sub:pub_example().
ok
what is wrong?
Hi guys,
I've picked up an issue with the current pub/sub client. Basically from what I can tell, the process handling the TCP connection waits for the controlling process (the one that ack's receipt of a message) to respond before it process the next message. I guess that's to provide a level of flow control.
In my case though, we received a large batch of messages in one go (around 7,000 or so I think) this filled up the message queue for the process handling the TCP connection (it's a gen_server) which then continues to grow and grow until I kill it.
I'm not sure how to fix this apart from adding a queue internally to the gen_server so that it serves messages from that rather than keeping messages in the TCP queue...
In short, I'm receiving a burst of messages which fills up the message queue on the gen_server which never manages to recover...
Any ideas?
I believe eredis does not support Redis' pubsub ( http://redis.io/topics/pubsub )
Is someone already working on this, or is there interest in adding this feature?
8> {ok, C} = eredis:start_link().
** exception exit: {case_clause,{select_error,{unexpected_data,{ok,<<"-LOADING Redis is loading the dataset in memory\r\n">>}}}}
in function eredis_client:init/1
in call from gen_server:init_it/6
in call from proc_lib:init_p_do_apply/3
Is there a way to close a redis connection? I looked around in the source code, and it looks like there's no way currently.
I am passing the Eredis password param in the start_link,
Previously my password param was empty, now we have added a authentication to our redis server.
When i try to pass the password param "xcvvcnbmn", i am seeing the below crash
Please do the needful
I am able to connect through redis-cli
=SUPERVISOR REPORT==== 28-Aug-2018::16:31:16 ===
Supervisor: {<0.268.0>,eredis_sup}
Context: start_error
Reason: {'EXIT',
{{badmatch,
{error,
{connection_error,
{authentication_error,
{unexpected_data,{error,closed}}}}}},
[{eredis,start_link,6,
[{file,"src/eredis.erl"},{line,76}]},
{supervisor,do_start_child,2,
[{file,"supervisor.erl"},{line,365}]},
{supervisor,start_children,3,
[{file,"supervisor.erl"},{line,348}]},
{supervisor,init_children,2,
[{file,"supervisor.erl"},{line,314}]},
{gen_server,init_it,6,
[{file,"gen_server.erl"},{line,328}]},
{proc_lib,init_p_do_apply,3,
[{file,"proc_lib.erl"},{line,247}]}]}}
Offender: [{pid,undefined},
{id,eredis},
{mfargs,{eredis,start_link,[]}},
{restart_type,temporary},
{shutdown,5000},
{child_type,worker}]
I've discovered race condition while testing reconnection logic. Here below is setup I'm using:
eredis:start_link
eredis_client
state.When connection dies and socket receives tcp_closed message eredis_client:reconnect_loop
is called in a separate process where it:
There are the following issues with described approach:
reconnect_loop
is executed) receives tcp_closed
message what causes eredis client process using dead socketconnection_ready
message while socket is undefined what causes process termination on unhandled_message
Is it safe to share the same connection? (call from 2 or more erlang processes.)
Thanks,
Hi, sometimes we have Docker configured with ipv6 resolving, but Redis server is only listening on ipv4.
So redis_client would resolve ipv6, try to connect and fail with a pretty non-descriptive eaddrnotavail
. After that people would try to do telnet localhost 6379
and it would work. They would try to do gen_tcp:connect("localhost", 6379, []).
and it would work. But eredis would not work.
eredis would basically do that behind the scene:
gen_tcp:connect({0,0,0,0,0,0,0,1}, 6379, []) -> {error,eaddrnotavail}
I doubt this code is even needed:
get_addr({local, Path}) ->
{ok, {local, {local, Path}}};
get_addr(Hostname) ->
case inet:parse_address(Hostname) of
{ok, {_,_,_,_} = Addr} -> {ok, {inet, Addr}};
{ok, {_,_,_,_,_,_,_,_} = Addr} -> {ok, {inet6, Addr}};
{error, einval} ->
case inet:getaddr(Hostname, inet6) of
{error, _} ->
case inet:getaddr(Hostname, inet) of
{ok, Addr}-> {ok, {inet, Addr}};
{error, _} = Res -> Res
end;
{ok, Addr} -> {ok, {inet6, Addr}}
end
end.
It would be much cleaner solution to just use gen_tcp:connect/3
logic and pass State#state.host
as a first argument, without resolving it first.
If people really need to use ipv6, they could pass inet6 inside of SocketOpts.
$ make
mkdir -p ebin
cp -f -- src/eredis.app.src ebin/eredis.app
sed "s/{{EXTRA_OPTS}}//" Emakefile.src > Emakefile
erl -noinput -eval 'up_to_date = make:all()' -s erlang halt
Recompile: src/eredis_sub_client
include/eredis.hrl:24: type queue() undefined
{"init terminating in do_boot",{{badmatch,error},[{erl_eval,expr,3,[]}]}}
Crash dump is being written to: erl_crash.dump...done
init terminating in do_boot ()
Makefile:8: recipe for target 'compile' failed
make: *** [compile] Error 1
$ rebar compile
==> eredis (compile)
Compiled src/basho_bench_driver_erldis.erl
Compiled src/eredis_sub_client.erl
Compiled src/eredis_client.erl
Compiled src/eredis_sub.erl
Compiled src/basho_bench_driver_eredis.erl
Compiled src/eredis.erl
Compiled src/eredis_parser.erl
BTW embeded rebar
is quite outdated.
$ ./rebar --version
rebar version: 2 date: 20110304_023706 vcs: git d725e5f
I'm using Erlang R15B03 (erts-5.9.3.1) and eredis-1.1.0 for a project. when I execute HINCRBYFLOAT command as below I always get <<543>> as value.
# erl -pa ebin/
Erlang R15B03 (erts-5.9.3.1) [source] [64-bit] [smp:4:4] [async-threads:0] [hipe] [kernel-poll:false]
Eshell V5.9.3.1 (abort with ^G)
1> {ok, C} = eredis:start_link().
{ok,<0.34.0>}
2> eredis:q(C, ["HINCRBYFLOAT", "foo", "bar", 0]).
{ok,<<"543">>}
Hello,
From my reading of the eredis documentation, it seems to me that if the connection to redis fails, eredis itself should not fail and, when the connection recovers, requests should work again. Is that correct or have I misread what is possible (highly likely as I am very new to erlang)?
So, my example is that if I compile eredis and point it at a redis server, I can successfully do commands, like this:
rebar compile
erl -pa /ebin
{ok,C} = eredis:start_link("my-redis-location", 6379, 0, "", 5000).
{ok,<<"PONG">>} = eredis:q(C, ["PING"]).
And, when I physically disconnect my network cable, I get an error (which I would expect):
eredis:q(C, ["PING"]).
** exception exit: {timeout,{gen_server,call,
[<0.35.0>,
{request,[[<<"*">>,"1",<<"\r\n">>],
[[<<"$">>,"4",<<"\r\n">>,<<"PING">>,<<"\r\n">>]]]},
5000]}}
in function gen_server:call/3 (gen_server.erl, line 212)
When I reconnect my network cable (and wait for the connection to start working again), I was hoping that requests would start working again but, instead, I only get errors:
eredis:q(C, ["PING"]).
** exception exit: {noproc,{gen_server,call,
[<0.35.0>,
{request,[[<<"*">>,"1",<<"\r\n">>],
[[<<"$">>,"4",<<"\r\n">>,<<"PING">>,<<"\r\n">>]]]},
5000]}}
in function gen_server:call/3 (gen_server.erl, line 212)
The difference between the second error and the first is that the second mentions noproc
instead of timeout
. I assume that the eredis process has died.
Is it possible to make it such that the process doesn't die and it starts working again once the connection is working again?
Of course, I am, probably, misunderstanding how processes should work in the erlang world!
last tag v1.0.6 is from July 2013
Why there is not a pool to control the connections like reddy?
i change the source and authenticate success
eredis_client.erl #351
authenticate(Socket, Password) ->
do_sync_command(Socket, eredis:create_multibulk(["AUTH", Password])).
If an eredis client fails its first connection-attempt it will spawn_link
a re-connection process.
This re-connection process will run until it succeeds.
But, if the connection attempts continuously fails and the user stops the eredis client, the spawned process is not terminated.
You will have an unexpected process running that attempts to connect to a previously used Redis instance.
A probable reason for this can be that eredis_client is stopped with reason normal
, and an exit signal with reason normal
is ignored by the re-connection process. See http://erlang.org/doc/reference_manual/processes.html#receiving-exit-signals
Compiling /deps/eredis/src/eredis_sub_client.erl
Line 24: error {undefined_type,{queue,0}} in "/deps/eredis/include/eredis.hrl"
ERROR: []
escript: exception error: no function clause matching
lists:flatten({return,{return,[{error,[]}]}}) (lists.erl, line 615)
in function mad:main/1 (/Users/5HT/depot/synrc/mad/src/mad.erl, line 17)
in call from escript:run/2 (escript.erl, line 757)
in call from escript:start/1 (escript.erl, line 277)
in call from init:start_it/1
in call from init:start_em/1
Hello,
Right now the tcp options are hard coded and there is no way I think to specify additional options like:
{keepalive, boolean()} for example.
Might be nice to have a way to specify those when we create the connection
I wanted to ask if you guys are actively maintaining this. I have just noticed that the latest tag (v1.0.8
) is nearly two years old and the new changes have not been tagged yet (or documented for that matter). I also noticed that some people are eager (as on #90) to migrate to rebar3
and publishing on hex. So the question is if you have any plans/enough time to do this, is it desired at all, and if I should send a pull request?
This is with eredis_cluster ~> 0.5.12
When using eredis pointing to a redis cluster endpoint with large number of shards, I get error :nxdomain. The only workaround is to use a list of ip addresses.
It is because, :inet.getaddr/2 unable to handle dns lookups that result in a large answers. Note however that :inet_res.gethostbyname/1 works fine likely because it reissues the dns lookup over TCP when it finds that the first query had the truncate bit set.
Offending code here: https://github.com/wooga/eredis/blob/master/src/eredis_client.erl#L335 (line 335, and line 307)
Below is a sample iex output that shows the error
Note the :nxdomain error in the second command, same hostname works fine in the fourth command.
iex(tango@2e76e9718be1)69> :inet.getaddr('small-redis-cluster.kk5zzw.clustercfg.use1.cache.amazonaws.com', :inet)
{:ok, {10, 99, 17, 14}}
iex(tango@2e76e9718be1)70> :inet.getaddr('large-redis-cluster.kk5zzw.clustercfg.use1.cache.amazonaws.com', :inet)
{:error, :nxdomain}
iex(tango@2e76e9718be1)71> :inet_res.gethostbyname('small-redis-cluster.kk5zzw.clustercfg.use1.cache.amazonaws.com')
{:ok,
{:hostent,
'small-redis-cluster.kk5zzw.clustercfg.use1.cache.amazonaws.com', [],
:inet, 4,
[
{10, 99, 23, 178},
{10, 99, 31, 149},
{10, 99, 22, 232},
{10, 99, 6, 27},
{10, 99, 17, 14},
{10, 99, 1, 221},
{10, 99, 2, 67},
{10, 99, 1, 59}
]}}
iex(tango@2e76e9718be1)72> :inet_res.gethostbyname('large-redis-cluster.kk5zzw.clustercfg.use1.cache.amazonaws.com')
{:ok,
{:hostent, 'large-redis-cluster.kk5zzw.clustercfg.use1.cache.amazonaws.com', [],
:inet, 4,
[
{10, 99, 59, 135},
{10, 99, 57, 16},
{10, 99, 59, 160},
{10, 99, 56, 194},
{10, 99, 56, 232},
{10, 99, 57, 166},
{10, 99, 57, 110},
{10, 99, 60, 8},
{10, 99, 57, 71},
{10, 99, 59, 89},
{10, 99, 57, 36},
{10, 99, 59, 202},
{10, 99, 56, 205},
{10, 99, 57, 149},
{10, 99, 59, 14},
{10, 99, 59, 230},
{10, 99, 61, 124},
{10, 99, 61, 224},
{10, 99, 60, 182},
{10, 99, 60, 109}
]}}
Waiting for ack in redis pub sub is kind of blocking. y do we need that?
Hi
we are using eredis-client with otp-19 and elixir 1.6.6 in our application whenever following things appeared in crash log , it is killing my application. I am using Elastic Cache Single node Redis. Any Idea?
crasher:
initial call: eredis_client:init/1
pid: <0.24202.0>
registered_name: []
exception exit: {bad_return_value,empty_queue}
in function gen_server:terminate/7 (gen_server.erl, line 812)
ancestors: [<0.24201.0>]
messages: [{tcp,#Port<0.90462>,
<<"00\blanguagem\x00\x00\x00\x02hid\x00\x13profile_image_smallm\x00\x00\x00\x00d\x00\x04typed\x00\x03nild\x00\rcreated_at_tsb[\xc5\xe0\xd1d\x00\akeywordm\x00\x00\x00\x06PMMODId\x00\ais_pagem\x00\x00\x00\x00d\x00\x0fis_voke_allowedd\x00\x04trued\x00\ahashtagl\x00\x00\x00\x04t\x00\x00\x00\bm\x00\x00\x00\x04iconm\x00\x00\x00Yhttps://s3.ap-south-1.amazonaws.com/ok.bots.image/Testing+image/ta_icon_tags/politics.pngm\x00\x00\x00\x02idaXm\x00\x00\x00\x0cis_followingd\x00\x04truem\x00\x00\x00\x05titlem\x00\x00\x00\bpoliticsm\x00\x00\x00\btitle_enm\x00\x00\x00\bPoliticsm\x00\x00\x00\btitle_him\x00\x00\x00\x15\xe0\xa4\xb0\xe0\xa4\xbe\xe0\xa4\x9c\xe0\xa4\xa8\xe0\xa5\x80\xe0\xa4\xa4\xe0\xa4\xbfm\x00\x00\x00\btitle_knm\x00\x00\x00\x00m\x00\x00\x00\btitle_tam\x00\x00\x00\x15\xe0\xae\x85\xe0\xae\xb0\xe0\xae\x9a\xe0\xae\xbf\xe0\xae\xaf\xe0\xae\xb2\xe0\xaf\x8dt\x00\x00\x00\bm\x00\x00\x00\x04iconm\x00\x00\x00\x00m\x00\x00\x00\x02idasm\x00\x00\x00\x0cis_followingd\x00\x05falsem\x00\x00\x00\x05titlem\x00\x00\x00\x06pmmodim\x00\x00\x00\btitle_enm\x00\x00\x00\aPM Modim\x00\x00\x00\btitle_him\x00\x00\x00\x0fPM \xe0\xa4\xae\xe0\xa5\x8b\xe0\xa4\xa6\xe0\xa5\x80m\x00\x00\x00\btitle_knm\x00\x00\x00\x00m\x00\x00\x00\btitle_tam\x00\x00\x00\x0f\xe0\xae\xae\xe0\xaf\x87\xe0\xae\xbe\xe0\xae\x9f\xe0\xae\xbft\x00\x00\x00\bm\x00\x00\x00\x04iconm\x00\x00\x00\x00m\x00\x00\x00\x02idb\x00\x00i\x93m\x00\x00\x00\x0cis_followingd\x00\x05falsem\x00\x00\x00\x05titlem\x00\x00\x00\rprim">>}]
links: [<0.24201.0>]
dictionary: []
trap_exit: false
status: running
heap_size: 610
stack_size: 27
reductions: 833
neighbours:
neighbour: [{pid,<0.24201.0>},
{registered_name,[]},
{initial_call,{cowboy_protocol,init,4}},
{current_function,{gen,do_call,4}},
{ancestors,[]},
{messages,[{#Ref<0.0.4.61368>,{ok,<<"OK">>}}]},
{links,[<0.641.0>,<0.24202.0>,#Port<0.90452>]},
{dictionary,
[{logger_metadata,
{true,
[{request_id,
<<"4gp55n1e0skebdc78j5lcgptsteplg5f">>}]}}]},
{trap_exit,false},
{status,runnable},
{heap_size,1598},
{stack_size,64},
{reductions,1969}]
[os_mon] cpu supervisor port (cpu_sup): Erlang has closed
[os_mon] memory supervisor port (memsup): Erlang has closed
E:\github\eredis>d:/tools/rebar/rebar.cmd doc
==> eredis (doc)
./src/eredis.erl, function q_noreply/2: at line 101: unknown error parsing refer
ence: {102,edoc_parser,
["syntax error before: ",["Executes"]]}.
edoc: skipping source file './src/eredis.erl': {'EXIT',error}.
edoc: error in doclet 'edoc_doclet': {'EXIT',error}.
ERROR: doc failed while processing E:/github/eredis: {'EXIT',error}
Using eredis, can I connect to local redis server through unix socket? e.g. /var/run/redis/redis.sock
I heard that communicating with redis by unix socket has better performance.
Thanks
Hi, I think it's a bit spartan to only offer a q(...)-style api from eredis.
One of the examples is:
eredis:q(["SET", "foo", "bar"]).
It would be nicer to offer this style I think:
eredis:set("foo", "bar").
Is there a particular reason why this was not done (besides save some work on the api-typing)? If there is interest in it, I can add this feature.
I got a crash with the following core stack. By using redis pool, no obvious reason why {unhandled_message,{connection_ready,#Port<0.1914682>}} is unhandled here.
------------------------------------>
[20601]: 17:03:36.790 [error] GenServer #PID<0.3744.3> terminating
[20601]: ** (stop) {:unhandled_message, {:connection_ready, #Port<0.1914682>}}
[20601]:
[20601]: =CRASH REPORT==== 14-Jul-2017::17:03:36 ===
[20601]: crasher:
[20601]: initial call: eredis_client:init/1
[20601]: pid: <0.3744.3>
[20601]: registered_name: []
[20601]: exception exit: {unhandled_message,{connection_ready,#Port<0.1914682>}}
[20601]: in function gen_server:terminate/7 (gen_server.erl, line 826)
[20601]: ancestors: [<0.1633.0>,eredis_pool_sup,<0.1378.0>]
[20601]: messages: []
[20601]: links: [<0.1632.0>,<0.1633.0>,#Port<0.1914682>]
[20601]: dictionary: []
[20601]: trap_exit: false
[20601]: status: running
[20601]: heap_size: 610
[20601]: stack_size: 27
[20601]: reductions: 1796
[20601]: neighbours:
[20601]:
[20601]: =SUPERVISOR REPORT==== 14-Jul-2017::17:03:36 ===
[20601]: Supervisor: {<0.1633.0>,poolboy_sup}
[20601]: Context: child_terminated
[20601]: Reason: {unhandled_message,{connection_ready,#Port<0.1914682>}}
[20601]: Offender: [{pid,<0.3744.3>},
[20601]: {id,eredis},
[20601]: {mfargs,{eredis,start_link,undefined}},
[20601]: {restart_type,temporary},
[20601]: {shutdown,5000},
[20601]: {child_type,worker}]
Hi,
Thanks for the lib. It's been a pleasure to use so far.
I am testing the pub/sub part of eredis, and from what I can see there' is no subscriber automatic reconnection, or am I missing something?
(STR: i connect to a redis instance, send some msg via redis-cli, receive them then, restart the redis-server, relaunch redis-cli, send more command -> nothing is received on the process listenening to subscribe.)
cheers,
Max
OS: Fedora 27
$ ./rebar eunit
=ERROR REPORT==== 16-Feb-2018::22:12:18 ===
** Generic server <0.118.0> terminating
** Last message in was {tcp,#Port<0.34473>,
<<"*3\r\n$7\r\nmessage\r\n$3\r\nfoo\r\n$2\r\n12\r\n">>}
** When Server state == {state,"127.0.0.1",6379,<<>>,100,#Port<0.34473>,
{pstate,undefined,undefined},
[<<"foo">>],
{#Ref<0.279932551.3633315841.178106>,<0.91.0>},
{[{message,<<"foo">>,<<"11">>,<0.118.0>},
{message,<<"foo">>,<<"10">>,<0.118.0>},
{message,<<"foo">>,<<"9">>,<0.118.0>},
{message,<<"foo">>,<<"8">>,<0.118.0>},
{message,<<"foo">>,<<"7">>,<0.118.0>},
{message,<<"foo">>,<<"6">>,<0.118.0>},
{message,<<"foo">>,<<"5">>,<0.118.0>},
{message,<<"foo">>,<<"4">>,<0.118.0>},
{message,<<"foo">>,<<"3">>,<0.118.0>}],
[{message,<<"foo">>,<<"2">>,<0.118.0>}]},
10,exit,need_ack}
** Reason for termination ==
** max_queue_size
eredis_tests: connect_test...*skipped*
undefined
*unexpected termination of test process*
::{connection_error,econnrefused}
=======================================================
Failed: 0. Skipped: 0. Passed: 43.
One or more tests were cancelled.
Cover analysis: /home/maqbool/OpenSource/eredis/.eunit/index.html
ERROR: One or more eunit tests failed.
ERROR: eunit failed while processing /home/maqbool/OpenSource/eredis: rebar_abort
If get_all_messages might receive more than one message, I think it should be changed to:
get_all_messages(Acc) ->
receive
M ->
get_all_messages([M | Acc])
after 0 ->
lists:reverse(Acc)
end.
This happens when I try to use eredis on ubuntu. It compiles fine, without errors, connects fine (or so it seems), but is not able to execute commands.
5> {ok, C} = eredis:start_link("localhost", 6379, 10, []).
{ok,<0.43.0>}
6> {ok, <<"OK">>} = eredis:q(C, ["SET", "un:bla", "1234"]).
=ERROR REPORT==== 11-Aug-2011::13:01:44 ===
** Generic server <0.43.0> terminating
** Last message in was {tcp,#Port<0.728>,<<"+OK\r\n">>}
** When Server state == {state,"localhost",6379,<<>>,<<"10">>,#Port<0.728>,
{pstate,undefined,undefined},
{[{<0.40.0>,#Ref<0.0.0.55>}],[]}}
** Reason for termination ==
** {'module could not be loaded',[{binary,match,[<<"OK\r\n">>,<<"\r\n">>]},
{eredis_parser,get_newline_pos,1},
{eredis_parser,parse_simple,1},
{eredis_parser,parse,2},
{eredis_client,handle_response,2},
{eredis_client,handle_info,2},
{gen_server,handle_msg,5},
{proc_lib,init_p_do_apply,3}]}
** exception exit: undef
in function binary:match/2
called as binary:match(<<"OK\r\n">>,<<"\r\n">>)
in call from eredis_parser:get_newline_pos/1
in call from eredis_parser:parse_simple/1
in call from eredis_parser:parse/2
in call from eredis_client:handle_response/2
in call from eredis_client:handle_info/2
in call from gen_server:handle_msg/5
in call from proc_lib:init_p_do_apply/3
7>
Hi,
I am not sure it is a bug or not, if open a tcp server instead of redis server, connect still works fine.
Reproduce step:
Are there plans to add support for disque?
https://github.com/antirez/disque
It uses the same protocol and only need some logic to handle trying different nodes in case of failure or load.
Hi,
The concurrent connections in my project was about 30,000. I could find CRASH: {connection_error,{connection_error,eaddrnotavail}} in a percentage of 0.1%.
The reuseaddr is set to true and looks like it is the root cause. The client would try to reuse the same port in time_wait status, but encounters eaddrnotavail error.
Please refer to http://stackoverflow.com/questions/17606503/redis-exception-raised-in-gen-server/26523211#26523211
After change the code to:
-define(SOCKET_OPTS, [binary, {active, once}, {packet, raw}, {reuseaddr, false}]).
There is no more eaddrnotavail error.
As is, eredis
logs something like
... [error] CRASH REPORT Process <0.x.0> with 0 neighbours exited with reason: {error, connection_error} in gen_server:init_it/6
when eredis_client:init
fails due to a connection error.
{stop, {connection_error, Reason}}
could be changed to {stop, {shutdown, {connection_error, Reason}}}
and this would prevent the log message the supervisor creates, while also informing that connection didn't go as expected.
@knutin: would you be interested in such a change with a PR? This doesn't seem to break interface, because it's documented as {ok, _} | {error, _}
, thus all initialization errors are handled the same.
I am coming from Elixir, so the stack trace from Erlang is a little foreign to me; sorry if this is a easy fix.
I am able to compile against the provided version of rebar
root@33175fa19b42:/src/eredis# ./rebar --version
rebar version: 2 date: 20110304_023706 vcs: git d725e5f
root@33175fa19b42:/src/eredis# ./rebar compile
==> eredis (compile)
But against the latest version, I am not.
root@33175fa19b42:/src/eredis# rebar --version
rebar 2.5.1 17 20150421_125738 git 2.5.1-180-g858fb4f
root@33175fa19b42:/src/eredis# rebar compile
==> eredis (compile)
ERROR: compile failed while processing /src/eredis: {'EXIT',
{function_clause,
[{filename,join,[[]],[{file,"filename.erl"},{line,392}]},
{rebar_erlc_compiler,expand_include_lib_path,1,
[{file,"src/rebar_erlc_compiler.erl"},{line,647}]},
{rebar_erlc_compiler,process_attr,3,
[{file,"src/rebar_erlc_compiler.erl"},{line,597}]},
{rebar_erlc_compiler,parse_attrs,2,
[{file,"src/rebar_erlc_compiler.erl"},{line,565}]},
{rebar_erlc_compiler,modify_erlcinfo,4,
[{file,"src/rebar_erlc_compiler.erl"},{line,400}]},
{rebar_erlc_compiler,'-update_erlcinfo_fun/2-fun-0-',4,
[{file,"src/rebar_erlc_compiler.erl"},{line,359}]},
{lists,foldl,3,[{file,"lists.erl"},{line,1261}]},
{rebar_erlc_compiler,init_erlcinfo,2,
[{file,"src/rebar_erlc_compiler.erl"},{line,349}]}]}}
When using the provided Makefile, some commands fail.
This is due to the long options (--xxxx) used in mkdir
, cp
, rm
.
Switching to short options fixes the problem.
I have a slightly larger application. Redis (and eredis) are in no way essential for its functionality. Only "good to have sometimes".
If I shut down redis after starting my application, I'm totally fine now. Eredis (via poolboy) gets reconnected when and if redis comes back up.
But I can't seem to be able to start my applications without having redis up. Poolboy/eredis crashes and brings down my app that spawns it. I could flag that pool as transient, but that means it will never start again if redis becomes available.
So, do you think it's a good idea modify eredis in a way that it's able to start, and connect to redis later if at all?
I am willing to do the required changes myself, if there is a will for them being accepted, and after we have an understanding what to change exactly.
So what do you guys think?
When we use cluster in eredis_cluster, the library does not uses the replicas of Redis. Is there a plan to add replica support in the library ?
in README eredis:start_link/4 is documented to be called like eredis:start_link(Host, Port, Password, DB). This is not true. The code requres that you pass the arduments in different order eredis:start_link(Host, Port, DB, Password)
Hello!
When I use this library my RAM decrease from 600MB to 150MB (yes, i get site homepage many times via wrk utility). But after that free RAM not restores -:(( I have no such problems with Erlang Mnesia for example. Maybe there is exists function eredis:CLOSE_link() in this lib???
A MULTI ... EXEC sequence can include calls that return multibulks, and will then be embedded inside the multibulk reply to EXEC.
e.g., to pop stuff older than a certain time from a sorted set:
MULTI
ZRANGEBYSCORE somekey -inf
ZREMRANGEBYSCORE somekey -inf
EXEC
This will currently crash eredis with an error like "no function clause matching eredis_parser:parse_bulk(<<"*2\r\n$3\r\nhah\r\n$4\r\nwhat\r\n:2\r\n">>)"
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.