roundrobin processing of sockets in select system call to prevent starvation

104 Views Asked by At

I am working on an application which connects to a group of servers via sockets TCP/IP.

Some of the servers have a lot of data to send and/or send fastly while some have very less relatively and/or send slowly.

In this scenario to prevent starvation of servers that are sending slowly, does it make sense to round-robin processing of sockets in the select system call

something like,

//pseudo code for Round-Robin
    ...
    int start_fd = 0;
    
    while (true) {
        fd_set tempfds;
        FD_ZERO(&tempfds);
    
        for (int i = 0; i < num_servers; ++i) {
            // Calculate the index of the socket descriptor
            // to be checked using round-robin scheduling.
            int index = (i + start_fd) % num_servers;
            int sockfd = sockets[index];
            FD_SET(sockfd, &tempfds);
        }
    
        if (select(maxfd+1, &tempfds, NULL, NULL, NULL) < 0) {
            perror("select");
            exit(3);
        }
    
        bool data_processed = false;
    
        for (int i = 0; i < num_servers; ++i) {
            // Calculate the index of the socket descriptor
            // to be checked using round-robin scheduling.
            int index = (i + start_fd) % num_servers;
            int sockfd = sockets[index];
    
            if (FD_ISSET(sockfd, &tempfds)) {
                ssize_t n = recv(sockfd, buffer, sizeof(buffer)-1, 0);
                if (n <= 0) {
                    if (n < 0) perror("recv");
                    close(sockfd);
                    sockets.erase(sockets.begin() + index);
                    num_servers -= 1;
                } else {
                    buffer[n] = '\0';
                    printf("Received from server %d: %s\n", index, buffer);
                    data_processed = true;
                    start_fd = (index + 1) % num_servers;
                    break;
                }
            }
        }
    
        if (!data_processed) {
            // If no data was processed this round (i.e., no servers have data available),
            // move on to the next server for the next round.
            start_fd = (start_fd + 1) % num_servers;
        }
    }
    ...
    //pseudo code for Non-Round-Robin
    maxFH = N//maximum file handle, say N connections total
while (true) {    
    select(call on all fds for reading upto maxFH)
// after each system call, start checking from the fd at index 0 for read readiness    
    for (int i=0; i < maxFH; i++)
    {
         if filehandleready(fds[i]) process(fds[i]);
    
    }
}

Please feel free to suggest other ways to handle starvation and fair handling. Just do not want few of the servers to fall too behind because of my application processing.

0

There are 0 best solutions below