Ejemplo n.º 1
0
void startServer() {
    int timer;
    fd_set rdfs;
    blockGroup* block_group;
    struct timeval tval;
    
    tval.tv_sec  = PING_TIMER;
    tval.tv_usec = 0; 
    
    block_group = newBlockGroup();
    block_group->server_socket = initServer();
    block_group->max_socket = block_group->server_socket;
            
    printf("[IMPORTANT] : Press Enter to Stop the Boss\n");  
    
    for ( ;; ) {
    
        FD_ZERO(&rdfs);
        setHandler(block_group, &rdfs);
    
        if( (timer = select(block_group->max_socket + 1, &rdfs, NULL, NULL, &tval)) == -1) {
            QUIT_MSG("Can't select : ");
        }
        
        if ( timer == 0 ) {
            tval.tv_sec = handlerPresence(block_group);  
        }

        #ifdef linux
        if( FD_ISSET(STDIN_FILENO, &rdfs) ) {
            break;            
        }
        else
        #endif 
        if( FD_ISSET(block_group->server_socket, &rdfs) ) {
            handleNewClient(block_group);      
        }
        else {
            handlerClient(block_group, &rdfs);
        }
    }
    
    printf("[BYE] Server stop\n\n");
    closeServer(block_group);
    
    return;
    
}
Ejemplo n.º 2
0
    void Master::acceptClientAsync(bool initial)
	{
		if (initial) {
			BOOST_LOG_SEV(log, LogLevel::Info) <<
			format("Listening for clients at %s.") % clientAcceptor.local_endpoint();
		}
		try {
			clientAcceptor.async_accept(waitingClient->tcpSocket(),
			[=](const boost::system::error_code& errorCode) {
				if (errorCode.value() == boost::asio::error::operation_aborted || disposed) {
					std::lock_guard<std::mutex> guard(clientAcceptorMutex);
					clientAcceptorRunning = false;
					clientAcceptorCV.notify_all();
					return;
				} else if (errorCode) {
					if (initial) {
						BOOST_LOG_SEV(log, LogLevel::Fatal) <<
						format("Accepting client connection failed: %s.") % errorCode;
					}
					std::lock_guard<std::mutex> guard(clientAcceptorMutex);
					clientAcceptorRunning = false;
					clientAcceptorCV.notify_all();
					return;
				} else {
					// New client connected.
					auto conn = waitingClient;
					
					// Prepare to accept the next client.
					{
						std::lock_guard<std::recursive_mutex> lock(clientsMutex);
						clients[conn->id()] = std::move(waitingClient);
						waitingClient = std::make_shared<MasterClient>(*this, conn->id() + 1,
																	   _parameters.allowVersionSpecification);
					}
					
					std::weak_ptr<MasterClient> weakConn(conn);
					
					// Setup "someone needs to respond to me" handler
					conn->onNeedsResponse.connect([this, weakConn](const std::shared_ptr<MasterClientResponse>& r) {
						
						auto conn = weakConn.lock();
						if (!conn) {
							// Unexpected...
							BOOST_LOG_SEV(log, LogLevel::Error) <<
							"onNeedsResponse raised by unexistent MasterClient.";
							return;
						}
						
						// Use balancer to choose a server.
						auto domain = bindClientToDomain(conn);
						 
						if (!domain) {
							r->reject("Could not find a suitable domain. Overload possible.");
							return;
						}
						
						auto version = domain->second;
						
						BOOST_LOG_SEV(log, LogLevel::Debug) <<
						format("Bound client '%d' to '%s' at '%s'.") % conn->id() %
						version % domain->first->nodeInfo().nodeName;
						
						// Make sure MasterClientResponse is in pendingClients
						// until it is done
						{
							std::lock_guard<std::recursive_mutex> lock(pendingClientsMutex);
							PendingClient pend;
							pend.response = r;
							pend.version = version;
							pendingClients.emplace(r->client()->id(), std::move(pend));
						}
						
						std::function<void(bool)> onResponded = [this, conn](bool) {
							std::lock_guard<std::recursive_mutex> lock(pendingClientsMutex);
							pendingClients.erase(conn->id());
						};
						
						r->onResponded.connect(onResponded);
						
						// It is not impossible that time-out already happened...
						if (r->isResponded()) {
							onResponded(false);
							return;
						}
						
						// Let node process the response.
						domain->first->acceptClient(r, version);
					});
					
					// Register client shutdown handler.
					conn->onShutdown.connect([this, weakConn]() {
						
						auto conn = weakConn.lock();
						if (!conn) {
							// Unexpected...
							BOOST_LOG_SEV(log, LogLevel::Error) <<
							"onShutdown raised by unexistent MasterClient.";
							return;
						}
						
						removeClient(conn->id());
					});
					
					// Start service
					conn->handleNewClient();
				}

				// Accept next connection
				acceptClientAsync(false);
			});
		} catch (...) {
			std::lock_guard<std::mutex> guard(clientAcceptorMutex);
			clientAcceptorRunning = false;
			clientAcceptorCV.notify_all();
			throw;
		}
	}