Ejemplo n.º 1
0
 protected void TWSCallbackClosed(string wskey)
 {
     lock (m_InFlight) {
         // releasing the existing tiingo websock callback handler enables the
         // BackgroundWork method to create another one
         m_InFlight.Remove(wskey);
         m_TWSCallback = null;
     }
 }
Ejemplo n.º 2
0
        public void BackgroundWork( )
        {
            // We're running on the background thread. Loop until we're told to exit...
            Logr.Log(String.Format("~A BackgroundWork thread started"));
            // Main loop for worker thread. It will briefly hold the m_InFlight lock when
            // it removes entries, and also the m_InputQueue lock in GetWork( ) as it
            // removes entries. DoQuandlQuery( ) will grab the cache lock when it's
            // adding cache entries. Obviously, no lock should be held permanently! JOS 2015-04-31
            while (true)
            {
                // Wait for a signal from the other thread to say there's some work.
                m_Event.WaitOne( );
                Dictionary <string, string> work = GetWork( );
                while (work != null)
                {
                    if (work["type"] == "stop")
                    {
                        // exit req from excel thread
                        Logr.Log(String.Format("~A BackgroundWork thread exiting"));
                        return;
                    }
                    string fkey = String.Format("{0}.{1}", work["type"], work["key"]);
                    Logr.Log(String.Format("~A BackgroundWork new request fkey({0})", fkey));

                    if (work["type"] == "quandl")
                    {
                        // run query synchronously here on background worker thread
                        bool ok = DoQuandlQuery(work);
                        // query done, so remove key from inflight, which will permit
                        // the query to be resubmitted
                        lock (m_InFlight) {
                            m_InFlight.Remove(fkey);
                        }
                    }
                    else if (work["type"] == "tiingo")
                    {
                        // run query synchronously here on background worker thread
                        bool ok = DoTiingoQuery(work);
                        // query done, so remove key from inflight, which will permit
                        // the query to be resubmitted
                        lock (m_InFlight) {
                            m_InFlight.Remove(fkey);
                        }
                    }
                    else if (work["type"] == "websock")
                    {
                        WSCallback wscb = new WSCallback(work, this.WSCallbackClosed);
                        // We don't want to remove the inflight key here as there will be
                        // async callbacks to WSCallback on pool threads when updates
                        // arrive on the SS websock. So we leave the key in place to
                        // prevent AddRequest, which is on the Excel thread, creating
                        // a request for a new WSCallback.
                        lock (m_InFlight) {
                            m_WSCallbacks.Add(fkey, wscb);
                        }
                    }
                    else if (work["type"] == "twebsock")
                    {
                        // We don't want to remove the inflight key here as there will be
                        // async callbacks to TWSCallback on pool threads when updates
                        // arrive on the tiingo websock. So we leave the key in place to
                        // prevent AddRequest, which is on the Excel thread, creating
                        // a request for a new TWSCallback.
                        lock (m_InFlight) {
                            if (m_TWSCallback == null)
                            {
                                m_TWSCallback = new TWSCallback(work, this.TWSCallbackClosed);
                                if (m_PendingTiingoSubs.Count > 0)
                                {
                                    m_TWSCallback.AddSubscriptions(m_PendingTiingoSubs);
                                    m_PendingTiingoSubs.Clear();
                                }
                            }
                        }
                    }
                    else if (work["type"] == "s2sub")
                    {
                        if (work["subcache"] == "twebsock")
                        {
                            // New subscription to a tiingo websock. If the TWSCallback
                            // doesn't exist yet cache it, but if it does pass it through
                            lock (m_InFlight) {
                                m_PendingTiingoSubs.Add(work);
                                if (m_TWSCallback != null)
                                {
                                    m_TWSCallback.AddSubscriptions(m_PendingTiingoSubs);
                                    m_PendingTiingoSubs.Clear();
                                }
                            }
                        }
                    }
                    work = GetWork( );
                }
                // We've exhausted the queued work, so reset the event so that we wait in the
                // WaitOne( ) invocation above until another thread signals that there's some
                // more work.
                m_Event.Reset( );
            }
        }