Exemple #1
0
        public (User[], AssetsCache, CompactFinTimeSeries <DateOnly, uint, float, uint>) GetAssuredConsistentTables()
        {
            // if client wants to be totally secure and consistent when getting subtables
            MemData localMemData = m_memData; // if m_memData swap occurs, that will not ruin our consistency

            return(localMemData.Users, localMemData.AssetsCache, localMemData.DailyHist);
        }
Exemple #2
0
        async Task ReloadDbDataIfChangedImpl()   // if necessary it reloads Historical and Realtime data
        {
            Console.WriteLine("*MemDb is not yet ready! ReloadDbData is in progress...");
            DateTime startTime = DateTime.UtcNow;

            // GA.IM.NAV assets have user_id data, so User data has to be reloaded too before Assets
            (bool isDbReloadNeeded, User[]? newUsers, List <Asset>?sqCoreAssets) = m_Db.GetDataIfReloadNeeded();
            if (!isDbReloadNeeded)
            {
                return;
            }

            // to minimize the time memDb is not consintent we create everything into new pointers first, then update them quickly
            var newAssetCache = AssetsCache.CreateAssetCache(sqCoreAssets !);

            // var newPortfolios = GeneratePortfolios();

            if (IsInitialized)
            {
                // if this is the periodic (not initial) reload of RedisDb, then we don't surprise clients by emptying HistPrices
                // and not having HistPrices for 20minutes. So, we download HistPrices before swapping m_memData pointer
                DateTime startTimeHist = DateTime.UtcNow;
                var      newDailyHist  = await CreateDailyHist(m_Db, newUsers !, newAssetCache); // downloads historical prices from YF. Assume it takes 20min

                if (newDailyHist == null)
                {
                    newDailyHist = new CompactFinTimeSeries <DateOnly, uint, float, uint>();
                }
                m_lastHistoricalDataReload   = DateTime.UtcNow;
                m_lastHistoricalDataReloadTs = DateTime.UtcNow - startTimeHist;

                var newMemData = new MemData(newUsers !, newAssetCache, newDailyHist);
                m_memData = newMemData; // swap pointer in atomic operation
                Console.WriteLine($"*MemDb is ready! (#Assets: {AssetsCache.Assets.Count}, #HistoricalAssets: {DailyHist.GetDataDirect().Data.Count}) in {m_lastHistoricalDataReloadTs.TotalSeconds:0.000}sec");
            }
            else
            {
                // if this is the first time to load DB from Redis, then we don't demand HistData. Assume HistData crawling takes 20min
                // many clients can survive without historical data first. MarketDashboard. However, they need Asset and User data immediately.
                // BrAccInfo is fine wihout historical. It will send NaN as a LastClose. Fine. Client will handle it.
                // So, we don't need to wait for Historical to finish InitDb (that might take 20 minutes in the future).
                // !!! Also, in development, we don't want to wait until All HistData arrives, but start Debugging code right away after starting the WebServer.
                // Clients of MemDb should handle properly if HistData is not yet ready (NaN and later Refresh).
                var newMemData = new MemData(newUsers !, newAssetCache, new CompactFinTimeSeries <DateOnly, uint, float, uint>());
                m_memData = newMemData; // swap pointer in atomic operation
                Console.WriteLine($"*MemDb is half-ready! (#Assets: {AssetsCache.Assets.Count}, #HistoricalAssets: 0)");
            }

            m_lastDbReload   = DateTime.UtcNow;
            m_lastDbReloadTs = DateTime.UtcNow - startTime;

            foreach (var brAccount in BrAccounts)
            {
                UpdateBrAccPosAssetIds(brAccount.AccPoss);
            }

            OnReloadAssetData_ReloadRtDataAndSetTimer();    // downloads realtime prices from YF or IEX
            OnReloadAssetData_ReloadRtNavDataAndSetTimer(); // downloads realtime NAVs from VBrokers
            EvDbDataReloaded?.Invoke();
        }