private static bool HandleError(NNTPCommands zCommand, VirtualConnection vConnection) { zCommand.LogError(zCommand.Error, vConnection); switch (zCommand.Error.Code) { case (int)NNTPCodes.DoNotTryAgain: case (int)NNTPCodes.TooManyConnections: case (int)NNTPCodes.GoodBye: zCommand.Status = WorkStatus.Failed; return(false); case (int)NNTPCodes.IDNotFound: case (int)NNTPCodes.NumberNotFound: zCommand.Status = WorkStatus.Missing; zCommand.Error.Tries += 1; return(true); default: zCommand.Status = WorkStatus.Failed; zCommand.Error.Tries += 1; return(true); } }
internal List <VirtualConnection> List(int ServerID = -1) { if (ServerID == -1) { return(zCol.ObjectList().Cast <VirtualConnection>().ToList()); } VirtualConnection vCon = null; List <VirtualConnection> cList = new List <VirtualConnection>(); foreach (int iC in ListID()) { vCon = Item(iC); if (vCon == null) { continue; } if (!(vCon.Server.ID == ServerID)) { continue; } cList.Add(vCon); } return(cList); }
private void Main(VirtualConnection vCon) { vCon.Enabled = true; try { Download(vCon); } catch (Exception ex) { if (!(vCon.Cancelled)) { vCon.Server.WriteStatus("Error: " + ex.Message); } } if (vCon.Cancelled) { vCon.Server.WriteStatus("Cancelled"); } vCon.Enabled = false; vCon.Remove(); if (vCon.Scheduler.Connections.Count() == 0) { foreach (VirtualSlot vSlot in vCon.Scheduler.Slots.List()) { vSlot.Status = SlotStatus.Paused; } } return; }
internal NNTPCommands Take(VirtualConnection vConnection) { object zObj = null; if (Status != SlotStatus.Downloading) { return null; } List<VirtualFile> sList = List(); if (sList.Count == 0) { return null; } foreach (VirtualFile vF in sList) { while ((Item(vF.ID) != null) && (!vF.IsEmpty)) { vF.SlotID = ID; // Should be done earlier zObj = vF.Take(); if (zObj == null) { if (vConnection.Cancelled) { return null; } continue; } return (NNTPCommands)zObj; } } return null; }
internal cNNTP(VirtualServer SVR, VirtualConnection VC) : base(SVR, VC) { vServer = SVR; this.Closed += new VirtualNNTP.ClosedEventHandler(VirtualEvents_Closed); this.Failed += new VirtualNNTP.FailedEventHandler(VirtualEvents_Failed); this.Received += new VirtualNNTP.ReceivedEventHandler(VirtualEvents_Received); this.Response += new VirtualNNTP.ResponseEventHandler(VirtualEvents_Response); this.Connected += new VirtualNNTP.ConnectedEventHandler(VirtualEvents_Connected); }
internal WaitHandle Wait(VirtualConnection vConnection, int lMilliseconds = 100) { List <WaitHandle> wList = new List <WaitHandle>(); wList.Add(vConnection.Idle.WaitHandle); wList.Add(vConnection.Token.Token.WaitHandle); WaitHandle wHandle = Common.WaitList(wList, lMilliseconds); if ((wHandle != null) && (wHandle.Handle == vConnection.Idle.WaitHandle.Handle)) { vConnection.Idle.Reset(); } return(wHandle); }
internal VirtualConnection Add(int ServerID) { VirtualServer zServer = zServers.Item(ServerID); if (zServer == null) { return(null); } VirtualConnection vCon = new VirtualConnection(zServers, zServer); if (!zCol.Add(vCon)) { return(null); } vCon.Start(); return(vCon); }
internal VirtualNNTP(VirtualServer SVR, VirtualConnection VC) { iServer = SVR; iConnection = VC; }
internal Task Task(VirtualConnection vConnection) { Action aMain = (Action)(() => Main(vConnection)); return(new Task(aMain, vConnection.Token.Token, TaskCreationOptions.LongRunning)); }
private void Download(VirtualConnection vCon) { long LastTicks; NNTPCommands pWork = null; IndexedCollection SwitchStack; while (vCon.Enabled) { vCon.Token.Token.ThrowIfCancellationRequested(); pWork = vCon.Scheduler.FindWork(vCon); if (pWork == null) { Wait(vCon); continue; } vCon.Token.Token.ThrowIfCancellationRequested(); LastTicks = DateTime.UtcNow.Ticks; pWork = vCon.ExecuteCommand(pWork); vCon.Token.Token.ThrowIfCancellationRequested(); if (pWork.Status == WorkStatus.Completed) { pWork.Statistics(pWork.Data.Length, DateTime.UtcNow.Subtract(new DateTime(LastTicks)).Ticks, vCon); } else { pWork.Statistics(0, DateTime.UtcNow.Subtract(new DateTime(LastTicks)).Ticks, vCon); string sMsg = null; bool bRet = HandleError(pWork, vCon); if (!bRet) { // Never auto-shutdown the last connection if (vCon.Scheduler.Connections.Count() < 2) { bRet = true; pWork.Error.Tries += 1; } } if (!bRet) { vCon.Enabled = false; sMsg = pWork.Error.Message; } if ((pWork.Error.Tries < (vCon.Scheduler.Count + 1)) || (!bRet)) { SwitchStack = vCon.Scheduler.SwitchStack(pWork.Segment.SlotID, vCon); if (SwitchStack != null) { pWork.Status = WorkStatus.Queued; if (SwitchStack.Add(pWork) != null) { pWork = null; } } } if (!bRet) { throw new Exception(sMsg); } } vCon.Token.Token.ThrowIfCancellationRequested(); if (pWork != null) { pWork.Progress(pWork.Expected, vCon); Process(pWork, vCon); pWork = null; } } }
private void Process(NNTPCommands zCommand, VirtualConnection vCon) { string sError = ""; try { VirtualSlot vSlot; //vCon.Server.WriteStatus("Decoding #" + zCommand.ID); if ((zCommand.Status == WorkStatus.Failed) || (zCommand.Status == WorkStatus.Missing)) { zCommand.Data = null; zCommand.Segment.LogError(zCommand.ID, zCommand.Error); //vCon.Scheduler.Slots.Log.Enqueue(zCommand.Error.Message); } //else //{ // DecodeArticle(zCommand); //} if (zCommand.Segment.Output.Store(zCommand.ID, zCommand)) { if (zCommand.Segment.Output.Finished) { zCommand.Segment.IsDecoded = true; vSlot = vCon.Scheduler.Slots.Item(zCommand.Segment.SlotID); if ((vSlot != null) && (vSlot.IsDecoded)) { bool bCompleted = false; List <string> cList = new List <string>(); foreach (VirtualFile vFile in vSlot.List()) { if (vFile.Output.Data.Length > 0) { bCompleted = true; break; } else { cList.Add(Common.MostFrequent(vFile.Errors.GetEnumerator())); } } if (bCompleted) { vSlot.Status = SlotStatus.Completed; } else { vSlot.StatusLine = Common.MostFrequent(cList.GetEnumerator()); if (vSlot.StatusLine.Length == 0) { vSlot.StatusLine = "No data"; } vSlot.Status = SlotStatus.Failed; } } } return; } throw new Exception("Store #" + zCommand.ID); } catch (Exception ex) { sError = "Decode: " + ex.Message; try { if (!vCon.Cancelled) { vCon.Server.WriteStatus(sError); } } catch {} } }