internal NNTPCommands FindWork(VirtualConnection vConnection) { //List<int> vCons; if (vConnection == null) { return(null); } if (vConnection.Server == null) { return(null); } NNTPCommands vCom = SearchRandomStack(vConnection); if (vCom != null) { return(vCom); } if (vConnection.Server.Priority == ServerPriority.Low) { return(null); } return(SearchRandomSlot(vConnection)); }
public NNTPCommands ExecuteCommand(NNTPCommands zCommand, CancellationToken cCancel) { cCommand = zCommand; cCommand.Reset(); cCommand.Status = WorkStatus.Downloading; VirtualEvent.Reset(); if (!base.Connect()) { Fail(980, "Connect"); return(cCommand); } VirtualEvent.Wait(5000, cCancel); if (cCancel.IsCancellationRequested) { return(cCommand); } if (!VirtualEvent.IsSet) { if ((!base.IsConnected) || (base.SocketStatus == NNTPStatus.Closed) || (base.SocketStatus == NNTPStatus.Connecting)) { base.Disconnect((int)NNTPCodes.SocketTimedOut, Common.TranslateError(SocketError.TimedOut).Message, false); } VirtualEvent.Wait(-1, cCancel); } return(cCommand); }
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); } }
private bool Queue(int lIndex, NNTPCommands nCom) { if (zCol.ContainsKey(lIndex)) { return(false); } return(zCol.Add(lIndex, nCom)); }
private NNTPCommands SearchRandomStack(VirtualConnection vConnection) { foreach (IndexedCollection vStack in WaitingStacks(vConnection.Server.ID)) { NNTPCommands zCommand = (NNTPCommands)vStack.Take(); if (zCommand != null) { return(zCommand); } } return(null); }
private NNTPCommands SearchRandomSlot(VirtualConnection vConnection) { foreach (VirtualSlot vSlot in RandomSlots()) // Global queue { NNTPCommands zCommand = (NNTPCommands)vSlot.Take(vConnection); if (zCommand != null) { return(zCommand); } } return(null); }
private bool Write(NNTPCommands nCom) { if (nCom == null) { return(false); } if (nCom.Data == null) { return(true); } if (nCom.Status != WorkStatus.Completed) { return(true); } if (nCom.Part != null) { if (zOffset > (nCom.Part.Begin - 1)) { return(false); } if (zOffset < (nCom.Part.Begin - 1)) { int zCorrect = ((nCom.Part.Begin - 1) - zOffset) + 1; byte[] zFill = new byte[zCorrect - 1]; zOut.Write(zFill, 0, zFill.Length); Interlocked.Add(ref zOffset, (int)zFill.Length); } if (zOffset != (nCom.Part.Begin - 1)) { return(false); } } nCom.Data.Position = 0; nCom.Data.CopyTo(zOut); Interlocked.Add(ref zOffset, (int)nCom.Data.Length); return(true); }
internal bool Store(int lIndex, NNTPCommands nCom) { if (lIndex != zIndex) { return(Queue(lIndex, nCom)); } bool ret = Write(nCom); Interlocked.Increment(ref zIndex); if (ret) { while (zCol.ContainsKey(zIndex)) { NNTPCommands gCom = (NNTPCommands)zCol.Take(); if (gCom == null) { break; } if (gCom.ID != zIndex) { break; } if (!Write(gCom)) { break; } Interlocked.Increment(ref zIndex); } } if (zTotal == (zIndex - 1)) { bFinished = true; } return(ret); }
internal NNTPCommands ExecuteCommand(NNTPCommands zCommand) { return(zNNTP.ExecuteCommand(zCommand, Token.Token)); }
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 bool DecodeArticle(NNTPCommands zCommand) { int zTotal = 0; string zLine = null; ArticleDecoder decoder = null; StreamReader sr = Common.GetReader((MemoryStream)zCommand.Data); while (!sr.EndOfStream) { zLine = sr.ReadLine(); zTotal += zLine.Length + 2; if (zLine.Length == 0) { break; } } if (!sr.EndOfStream) { zLine = sr.ReadLine(); int zLength = 0; switch (zLine.Split(' ')[0].ToLower()) { // Determine encoding case "=ybegin": // decoder = new yEnc(); // yEnc yDecoder = (yEnc)decoder; // zTotal += zLine + " "; // zCommand.File = yDecoder.DecodeHeader(zLine); // if (zCommand.File == null) { return false; } // string zPart = sr.ReadLine(); // zTotal += zPart + " "; // zCommand.Part = yDecoder.DecodePart(zPart); // if (zCommand.Part == null) { return false; } // zLength = (zCommand.Part.End - zCommand.Part.Begin) + 1; // zCommand.Data.Position = zTotal; // break; default: decoder = new Plain(); zCommand.Data.Position = zTotal; zLength = (int)(zCommand.Data.Length - zCommand.Data.Position); break; } zCommand.Data = decoder.DecodeBytes(zCommand.Data, zLength); return(true); } return(false); }
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 {} } }