Skip to content
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

remove websocket from fd_set when we know changes are pending #211

Open
briot opened this issue May 17, 2021 · 4 comments
Open

remove websocket from fd_set when we know changes are pending #211

briot opened this issue May 17, 2021 · 4 comments

Comments

@briot
Copy link
Contributor

briot commented May 17, 2021

When I wrote a server (not based on AWS), I was also ensuring that sockets for which we got a notification in epoll() were removed from the FD_Set until we had actually read or written everything to/from it. Otherwise, that socket keeps popping up in epoll which is inefficient. Is something like this necessary here (perhaps a new Issue, though)

Originally posted by @briot in #209 (comment)

@anisimkov
Copy link
Contributor

anisimkov commented May 17, 2021

I guess you mean
procedure Get
(Acceptor : in out Acceptor_Type;
Socket : out Socket_Access;
On_Error : access procedure (E : Exception_Occurrence) := null);
-- Returns a socket from the internal socket set which has data to read.
-- Should not be called simultaneously from different tasks.
-- On_Error needs to be able to catch Socket_Error on Accept_Socket or
-- on the Wait on the sockets. Accept_Socket and Wait on sockets could fail
-- if the server is processing too many keep-alive connections
-- simultaneously. Acceptor switched into Force timeouts in case of
-- Accept_Socket or Wait fail. The server could also use the On_Error
-- callback to decrease the number of simultaneous keep-alive connections.
-- If On_Error is null, the exception on error is propagated.
and

procedure Give_Back
(Acceptor : in out Acceptor_Type;
Socket : not null access Socket_Type'Class;
Success : out Boolean);
-- Give back socket which has been taken from Get routine above. Generally
-- this is called from a different task while the Get routine is blocked
-- waiting for a socket. Socket would not be given back in case of socket
-- queue size exceed Queue_Size Acceptor property and Success parameter
-- would return False value in this case.

in package AWS.Net.Acceptors, right ?
We can't have socket in set untill reading and writing it. If you have another mind to use socket set, you can use
package AWS.Net.Generic_Sets directly

@anisimkov
Copy link
Contributor

Maybe I understand wrong you question. We are removing socket from set when reading and writing it.

@briot
Copy link
Contributor Author

briot commented May 17, 2021

I was thinking of AWS.Net.WebSocket.Registry.Create_Set: we create a fd_set for poll or epoll, which includes all registered sockets. However, it might be the case that a previous call to poll() already told us there was some data to read, and we haven't had time to read it yet (or it is being read asynchronously). In this case, it reduces CPU usage significantly to not include the socket again in the next call to Create_Set.

In my own server, I wasn't recreating the set all the time, it was just modified when new sockets were added or others remove. To mark a socket as irrelevant for a call to poll, you simply change the set to make the descriptor negative (in which case it is automatically ignored by poll. When you have finished reading from the socket (or writing), you make the descriptor positive again in the set.

@anisimkov
Copy link
Contributor

I'l let @TurboGit answer this question, I do not know good enough the AWS websockets part.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants