/// <exception cref="System.IO.IOException"/> internal virtual void AddPeer(Peer peer, Sharpen.Thread t, DataXceiver xceiver) { lock (this) { if (closed) { throw new IOException("Server closed."); } peers[peer] = t; peersXceiver[peer] = xceiver; } }
public virtual void Run() { Peer peer = null; while (datanode.shouldRun && !datanode.shutdownForUpgrade) { try { peer = peerServer.Accept(); // Make sure the xceiver count is not exceeded int curXceiverCount = datanode.GetXceiverCount(); if (curXceiverCount > maxXceiverCount) { throw new IOException("Xceiver count " + curXceiverCount + " exceeds the limit of concurrent xcievers: " + maxXceiverCount); } new Daemon(datanode.threadGroup, DataXceiver.Create(peer, datanode, this)).Start( ); } catch (SocketTimeoutException) { } catch (AsynchronousCloseException ace) { // wake up to see if should continue to run // another thread closed our listener socket - that's expected during shutdown, // but not in other circumstances if (datanode.shouldRun && !datanode.shutdownForUpgrade) { Log.Warn(datanode.GetDisplayName() + ":DataXceiverServer: ", ace); } } catch (IOException ie) { IOUtils.Cleanup(null, peer); Log.Warn(datanode.GetDisplayName() + ":DataXceiverServer: ", ie); } catch (OutOfMemoryException ie) { IOUtils.Cleanup(null, peer); // DataNode can run out of memory if there is too many transfers. // Log the event, Sleep for 30 seconds, other transfers may complete by // then. Log.Error("DataNode is out of memory. Will retry in 30 seconds.", ie); try { Sharpen.Thread.Sleep(30 * 1000); } catch (Exception) { } } catch (Exception te) { // ignore Log.Error(datanode.GetDisplayName() + ":DataXceiverServer: Exiting due to: ", te); datanode.shouldRun = false; } } // Close the server to stop reception of more requests. try { peerServer.Close(); closed = true; } catch (IOException ie) { Log.Warn(datanode.GetDisplayName() + " :DataXceiverServer: close exception", ie); } // if in restart prep stage, notify peers before closing them. if (datanode.shutdownForUpgrade) { RestartNotifyPeers(); // Each thread needs some time to process it. If a thread needs // to send an OOB message to the client, but blocked on network for // long time, we need to force its termination. Log.Info("Shutting down DataXceiverServer before restart"); // Allow roughly up to 2 seconds. for (int i = 0; GetNumPeers() > 0 && i < 10; i++) { try { Sharpen.Thread.Sleep(200); } catch (Exception) { } } } // ignore // Close all peers. CloseAllPeers(); }