Example #1
0
        /// <summary>
        /// Handle pending and active data requests. Call this function regularly from the background worker thread.
        /// </summary>
        static public void Update()
        {
#if VERBOSE
            if (PendingRequestCount > 0 || ActiveRequestCount > 0)
            {
                Log.Write(Log.Levels.Verbose, "DataStore: Update() : " + PendingRequestCount + " requests pending, " + ActiveRequestCount + " active.");
            }
#endif
            // clean out finished requests.
            for (int i = 0; i < m_activeRequests.Count; i++)
            {
                DataRequestHTTP dr = m_activeRequests[i] as DataRequestHTTP;

                if (dr.State != DataRequestState.InProcess)
                {
#if VERBOSE
                    Log.Write(Log.Levels.Verbose, "DataStore: removing request " + dr.Source + " in state " + dr.State.ToString());
#endif
                    if (dr.State == DataRequestState.Finished && dr.RequestDescriptor.CompletionCallback != null)
                    {
#if VERBOSE
                        Log.Write(Log.Levels.Verbose, "DataStore: calling completion callback...");
#endif
                        dr.RequestDescriptor.CompletionCallback(dr);
                    }
                    else if (dr.State == DataRequestState.Error)
                    {
                        dr.State   = DataRequestState.Delayed;
                        dr.NextTry = DateTime.Now + TimeSpan.FromSeconds(120);
                        Log.Write(Log.Levels.Warning, "DataStore: request " + dr.Source + " has error, delaying until " + dr.NextTry.ToLongTimeString());
                        m_pendingRequests.Add(dr);
                    }
                    m_activeRequests.Remove(dr);
                }
            }

            lock (m_lock)
            {
                // if we're ready to activate new requests, first sort them according to current priority
                if (ActiveRequestCount < m_maxActiveRequests)
                {
                    foreach (DataRequest dr in m_pendingRequests)
                    {
                        dr.UpdatePriority();
                        //if (dr.Priority < 0)
                        //    dr.Cancel();

                        if (dr.State == DataRequestState.Delayed && dr.NextTry < DateTime.Now)
                        {
                            dr.State = DataRequestState.NoCache;
                        }
                    }

                    // also clean up cancelled requests
                    for (int i = 0; i < PendingRequestCount; i++)
                    {
                        DataRequest dr = m_pendingRequests[i] as DataRequest;

                        if (dr.State == DataRequestState.Queued)
                        {
                            if (dr.TryCache())
                            {
                                dr.RequestDescriptor.CompletionCallback(dr);
                                m_pendingRequests.Remove(dr);
                            }
                            else
                            {
                                dr.State = DataRequestState.NoCache;
                            }
                        }
                        if (dr.State == DataRequestState.Cancelled)
                        {
                            m_pendingRequests.Remove(dr);
                        }
                    }

                    m_pendingRequests.Sort();
                }
            }

            // see if we can start any more requests
            while ((PendingRequestCount > 0) && (ActiveRequestCount < m_maxActiveRequests))
            {
                // look for first pending request

                DataRequest drd = null;
                lock (m_lock)
                {
                    drd = m_pendingRequests[0] as DataRequest;

                    // if the top priority request is delayed, we won't find anything better.
                    // so we can break out immediately.
                    if (drd.State != DataRequestState.NoCache || drd.NextTry > DateTime.Now)
                    {
                        break;
                    }

                    m_pendingRequests.RemoveAt(0);
                }

#if VERBOSE
                Log.Write(Log.Levels.Verbose, "DataStore: Activating request for " + drd.Source);
#endif
//                if (!drd.TryCache())
                {
                    drd.Start();

                    m_activeRequests.Add(drd);
                }
            }
        }