amphp / redis

Efficient asynchronous communication with Redis servers, enabling scalable and responsive data storage and retrieval.

Home Page:https://amphp.org/redis

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Subscriber and publisher are leaking open files

fmdelvalle opened this issue · comments

I found that the Subscriber and RemoteExecutor open a RespSocket in the connect() promise but fail to close it, taking one open file for the life of the process. In a process with high concurrency of publishers and subscribers, it can easily reach the open file soft limit (usually 1024).

I think it is necessary to provide some way of disconnecting them, maybe in the destructor. I had to create disconnect() methods that call RespSocket::close() on the $connect member promise. Unfortunately, this triggers an exception in RespSocket::51 that I had to disable.

As a side note, I think the reference() and unreference() calls are unbalanced. I removed the reference() in Subscriber::unloadEmitter(), just before the yield $resp->write('unsubscribe', $channel); . I think the object should always have been referenced before.

Hey @fmdelvalle, thanks for the report! Why do you create that many publishers / subscribers? If you want to close the connection, you should be able to use the quit command already, no?

Regarding the reference() call, all you're trying to say that the call is unnecessary, because it should already be referenced at that point?

TBH I didn't think about sending the quit command, it could work, though it could trigger an exception too.

I need to open so many connections because I'm using Redis to manage communication between two processes, both with a pool of workers that need to communicate bidirectionally between both sides in a shared chat room. When a worker finishes, it drops the subscriber and publisher, but right now they never close some file descriptor, so on each worker run I lose two files. I could reduce the number of subscribers and publishers (reusing workers, i.e.), but I still think that not closing these file descriptors automatically can become a problem for other users too. I spent some time with this, maybe it's not critical for most use cases, but someday some developer may be browsing the issues page for a solution and this could give her a hint.

About the reference() call, at first I thought that this was creating the problem, so I logged and tested this, and it seems that calling reference() to send 'unsubscribe' is redundant, as it was called for 'subscribe' and unreference() was never called. Anyway, this was not related to the open files issue, so it is merely cosmetic.

BTW, thanks for your work, I moved from ReactPHP and I like using your library!