-
Notifications
You must be signed in to change notification settings - Fork 10.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Adapter life-cycle management and long-running process functionality #3662
Comments
The We've removed it since it was not needed anymore by the Redis adapter, but it seems other adapters may benefit from this. We can add it back in the form of a Promise, would it suit your use case? Edit: could you please merge the 3 other issues into this one please, it will be easier to follow 👼 |
Yes, making it promise-based would be ideal! |
I've worked around some of these issues in a really hacky way by making a factory for the adapter class and then firing callbacks on arguments passed into the factory, but its definitely not ideal. |
These extension points may be used by another adapter, in order to open or close a connection to a database for example. In Socket.IO v2, the join() method did accept a callback: ```js socket.join("room1", () => { io.to("room1").emit("hello"); }); ``` Depending on the adapter, it may now return a promise: ```js await socket.join("room1"); io.to("room1").emit("hello"); ``` Related: socketio/socket.io#3662
Depending on the adapter, Socket#join() may return: - nothing (in-memory and Redis adapters) - a promise (custom adapters) Breaking change: Socket#join() and Socket#leave() do not accept a callback argument anymore. Before: ```js socket.join("room1", () => { io.to("room1").emit("hello"); }); ``` After: ``` socket.join("room1"); io.to("room1").emit("hello"); // or await socket.join("room1"); for custom adapters ``` Note: the need for an asynchronous method came from the Redis adapter, which did override the Adapter#add() method in earlier versions, but this is not the case anymore. Reference: - https://github.com/socketio/socket.io/blob/2.3.0/lib/socket.js#L236-L258 - https://github.com/socketio/socket.io-adapter/blob/1.1.2/index.js#L56-L65 - socketio/socket.io-redis-adapter@05f926e Related: #3662
@bytenik I've updated the adapter class (socketio/socket.io-adapter@2e023bf) and the socket#join() method (129c641). I'm not sure about the public API for the Adapter#init() and Adapter#close() methods though. Should those methods be called by the end users directly? const server = require("http").createServer();
const io = require("socket.io")(server);
await this.of("/").adapter.init();
server.listen(3000);
// and then...
server.close();
await this.of("/").adapter.close(); |
@darrachequesne Awesome, that looks great. Right now the Adapter constructor is passed in, not a constructed adapter. socket.io constructs the adapter. So, there's no good way for the end user to call init or close. The lifespan is controlled by the io instance. |
Yes you are right. Currently, there is one Adapter per namespace, and they are constructed when:
But we could change that behavior, though I'm not really sure about the implications. |
@darrachequesne I don't think that there's anything inherently wrong with socket.io controlling the adapter lifecycle. I just think that in that case, the adapter needs an opportunity to start long running processes (init) and shutdown long running processes (close). So, both could return promises and socket.io would call those functions and then block until they resolve. |
Hey, I just got back to trying to implement these changes on my end. Is |
You are right, the We could call it here: Lines 79 to 81 in 1faa7e3
But we cannot await a constructor (the const io = new Server({
adapter: myCustomAdapter
}); Is there any problem with manually calling const io = new Server({
adapter: myCustomAdapter
});
await io.of("/").adapter.init(); I'm open to suggestions on this. |
Depending on the adapter, Socket#join() may return: - nothing (in-memory and Redis adapters) - a promise (custom adapters) Breaking change: Socket#join() and Socket#leave() do not accept a callback argument anymore. Before: ```js socket.join("room1", () => { io.to("room1").emit("hello"); }); ``` After: ``` socket.join("room1"); io.to("room1").emit("hello"); // or await socket.join("room1"); for custom adapters ``` Note: the need for an asynchronous method came from the Redis adapter, which did override the Adapter#add() method in earlier versions, but this is not the case anymore. Reference: - https://github.com/socketio/socket.io/blob/2.3.0/lib/socket.js#L236-L258 - https://github.com/socketio/socket.io-adapter/blob/1.1.2/index.js#L56-L65 - socketio/socket.io-redis-adapter@05f926e Related: socketio#3662
You want to:
Current behaviour
null
.Expected behaviour
Other information (e.g. stacktraces, related issues, suggestions how to fix)
This is particularly critical for the adapter that I have built that works with AWS SQS/SNS:
https://github.com/thinkalpha/socket.io-sqs (socket.io-sqs on npm)
For example, actions like
addAll
can't be properly handled in time; e.g. if youaddAll
a socket to room xxx and then immediately.to(xxx).emit(...)
, your message doesn't necessarily end up back at that socket.The text was updated successfully, but these errors were encountered: