Exemple #1
0
    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));
    }
Exemple #2
0
        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);
        }
Exemple #3
0
        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);
            }
        }
Exemple #4
0
 private bool Queue(int lIndex, NNTPCommands nCom)
 {
     if (zCol.ContainsKey(lIndex))
     {
         return(false);
     }
     return(zCol.Add(lIndex, nCom));
 }
Exemple #5
0
    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);
    }
Exemple #6
0
    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);
    }
Exemple #7
0
        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);
        }
Exemple #8
0
        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);
        }
Exemple #9
0
 internal NNTPCommands ExecuteCommand(NNTPCommands zCommand)
 {
     return(zNNTP.ExecuteCommand(zCommand, Token.Token));
 }
Exemple #10
0
        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;
                }
            }
        }
Exemple #11
0
        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);
        }
Exemple #12
0
        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 {}
            }
        }