Esempio n. 1
0
 /// <summary>Releases the unmanaged resources used by the <see cref="T:System.IO.Stream" /> and optionally releases the managed resources.</summary>
 /// <param name="disposing">true to release both managed and unmanaged resources; false to release only unmanaged resources.</param>
 protected override void Dispose(bool disposing)
 {
     if (disposing)
     {
         if (Interlocked.Exchange(ref _isDisposed, 1) == 0)
         {
             _currentStream.Dispose();
             if (_tempFile != null)
             {
                 var tmpName = _tempFile.Name;
                 _tempFile = null;
                 var tcs = new TaskCompletionSource <Nothing>();
                 CoreTaskHelper.RunAsyncFuncOnNewThread(async() =>
                 {
                     try
                     {
                         await CloseFile(tmpName);
                         tcs.SetResult(Nothing.Value);
                     }
                     catch (Exception ex)
                     {
                         tcs.SetException(ex);
                     }
                     return(Nothing.Value);
                 });
                 if (!tcs.Task.Wait(TimeSpan.FromSeconds(5)))
                 {
                     throw new TimeoutException();
                 }
             }
         }
     }
     base.Dispose(disposing);
 }
Esempio n. 2
0
        /// <summary>
        /// Параллельная обработка перечисления на разных сессиях.
        /// </summary>
        /// <typeparam name="TSrc">Тип данных.</typeparam>
        /// <typeparam name="T">Тип результата.</typeparam>
        /// <param name="src">Перечисление.</param>
        /// <param name="parallelFunc">Функция обоработки.</param>
        /// <returns>Результат.</returns>
        protected async ValueTask <T[]> ParallelizeOnSessions <TSrc, T>(IEnumerable <TSrc> src, Func <IEsentSession, TSrc, T> parallelFunc)
        {
            ValueTask <T> Do(IEsentSession session, TSrc el)
            {
                return(session.Run(() => parallelFunc(session, el)));
            }

            if (src == null)
            {
                throw new ArgumentNullException(nameof(src));
            }
            if (parallelFunc == null)
            {
                throw new ArgumentNullException(nameof(parallelFunc));
            }
            var tasks     = new List <ValueTask <T> >();
            var toDispose = new CompositeDisposable(null);

            try
            {
                foreach (var el in src)
                {
                    var session = await EsentProvider.GetSecondarySessionAndUse();

                    toDispose.AddDisposable(session.usage);
                    tasks.Add(Do(session.session, el));
                }
                return(await CoreTaskHelper.WhenAllValueTasks(tasks));
            }
            finally
            {
                toDispose.Dispose();
            }
        }
Esempio n. 3
0
 /// <summary>When overridden in a derived class, writes a sequence of bytes to the current stream and advances the current position within this stream by the number of bytes written.</summary>
 /// <param name="buffer">An array of bytes. This method copies <paramref name="count" /> bytes from <paramref name="buffer" /> to the current stream. </param>
 /// <param name="offset">The zero-based byte offset in <paramref name="buffer" /> at which to begin copying bytes to the current stream. </param>
 /// <param name="count">The number of bytes to be written to the current stream. </param>
 /// <exception cref="T:System.ArgumentException">The sum of <paramref name="offset" /> and <paramref name="count" /> is greater than the buffer length.</exception>
 /// <exception cref="T:System.ArgumentNullException">
 /// <paramref name="buffer" />  is null.</exception>
 /// <exception cref="T:System.ArgumentOutOfRangeException">
 /// <paramref name="offset" /> or <paramref name="count" /> is negative.</exception>
 /// <exception cref="T:System.IO.IOException">An I/O error occured, such as the specified file cannot be found.</exception>
 /// <exception cref="T:System.NotSupportedException">The stream does not support writing.</exception>
 /// <exception cref="T:System.ObjectDisposedException">
 /// <see cref="M:System.IO.Stream.Write(System.Byte[],System.Int32,System.Int32)" /> was called after the stream was closed.</exception>
 /// <filterpriority>1</filterpriority>
 public override void Write(byte[] buffer, int offset, int count)
 {
     _currentStream.Write(buffer, offset, count);
     if (!CoreTaskHelper.RunAsyncFuncOnNewThread(CheckStreamSize).Wait(TimeSpan.FromSeconds(10)))
     {
         throw new TimeoutException();
     }
 }
Esempio n. 4
0
 /// <summary>When overridden in a derived class, sets the length of the current stream.</summary>
 /// <param name="value">The desired length of the current stream in bytes. </param>
 /// <exception cref="T:System.IO.IOException">An I/O error occurs. </exception>
 /// <exception cref="T:System.NotSupportedException">The stream does not support both writing and seeking, such as if the stream is constructed from a pipe or console output. </exception>
 /// <exception cref="T:System.ObjectDisposedException">Methods were called after the stream was closed. </exception>
 /// <filterpriority>2</filterpriority>
 public override void SetLength(long value)
 {
     _currentStream.SetLength(value);
     if (!CoreTaskHelper.RunAsyncFuncOnNewThread(CheckStreamSize).Wait(TimeSpan.FromSeconds(10)))
     {
         throw new TimeoutException();
     }
 }
Esempio n. 5
0
        public async Task BlobStoreUploadBenchmarkParallel()
        {
            long          size;
            Stopwatch     sw;
            List <BlobId> id;

            using (var str = new MemoryStream())
            {
                var wr = new BinaryWriter(str);
                for (int i = 0; i < 1024 * 1024 * 2; i++)
                {
                    wr.Write(i);
                }
                wr.Flush();
                byte[] dataBuf = str.ToArray();
                size         = str.Length;
                str.Position = 0;
                id           = new List <BlobId>();
                sw           = new Stopwatch();
                sw.Start();
                var l = new object();

                async Task <Nothing> DoSave()
                {
                    using (var str2 = new MemoryStream(dataBuf))
                    {
                        var id1 = await _store.SaveBlob(new InputBlob()
                        {
                            BlobStream = str2,
                            Category   = "test",
                            UniqueName = Guid.NewGuid().ToString()
                        }, CancellationToken.None);

                        lock (l)
                        {
                            id.Add(id1);
                        }
                    }
                    return(Nothing.Value);
                }

                var toWait = Enumerable.Range(0, 5).Select(i => (Task)CoreTaskHelper.RunAsyncFuncOnNewThread(DoSave)).ToArray();

                await Task.WhenAll(toWait);

                sw.Stop();
                var sizeMb = (float)size / (1024 * 1024);
                var sec    = sw.Elapsed.TotalSeconds / id.Count;
                sw = new Stopwatch();
                sw.Start();
                Logger.LogMessage($"Время сохранения файла размером {id.Count}x{sizeMb:F2} Мб: {sec} сек, {sizeMb / sec} Мб/Сек");
            }
        }
Esempio n. 6
0
        private async Task <IList <IBoardPostEntity> > LoadEntities(IList <PostStoreEntityId> ids, PostStoreLoadMode mode)
        {
            ValueTask <List <IBoardPostEntity> > DoLoad(IList <PostStoreEntityId> toLoad)
            {
                return(OpenSession(session =>
                {
                    var result = new List <IBoardPostEntity>();
                    var loadContext = CreateLoadContext(session, true, true);
                    var loadContextToDispose = loadContext;
                    using (loadContextToDispose)
                    {
                        foreach (var id in toLoad)
                        {
                            Api.MakeKey(loadContext.table.Session, loadContext.table, id.Id, MakeKeyGrbit.NewKey);
                            if (Api.TrySeek(loadContext.table.Session, loadContext.table, SeekGrbit.SeekEQ))
                            {
                                var r = LoadBoardEntity(session, ref loadContext, mode);
                                result.Add(r);
                            }
                        }
                    }
                    return result;
                }));
            }

            if (ids == null)
            {
                throw new ArgumentNullException(nameof(ids));
            }
            mode = mode ?? DefaultLoadMode;

            IList <IBoardPostEntity> loaded;

            if (ids.Count > 4)
            {
                var toLoad      = ids.DistributeToProcess(3);
                var tasks       = toLoad.Select(DoLoad).ToArray();
                var taskResults = await CoreTaskHelper.WhenAllValueTasks(tasks);

                loaded = taskResults.SelectMany(r => r).ToList();
            }
            else
            {
                loaded = await DoLoad(ids);
            }

            if (mode.EntityLoadMode == PostStoreEntityLoadMode.Full)
            {
                await FillChildrenInLoadResult(loaded);
            }

            return(loaded);
        }
Esempio n. 7
0
        /// <summary>
        /// Все модули инициализированы.
        /// </summary>
        protected override async ValueTask <Nothing> OnAllInitialized()
        {
            await base.OnAllInitialized();

            try
            {
                ValueTask <Nothing> DoEnsureTableversion()
                {
                    return(InMainSessionAsync(EnsureTableversion));
                }

                async ValueTask <Nothing> DoUpdate()
                {
                    void SignalUpdateComplete()
                    {
                        _upgradeTcs.SetResult(Nothing.Value);
                    }

                    void SignalUpdateError(Exception ex)
                    {
                        _upgradeTcs.SetException(ex);
                    }

                    try
                    {
                        await TableVersionStatus.Instance.InitializeTableVersionOnce(DoEnsureTableversion);
                        await CreateOrUpgradeTables();

                        CoreTaskHelper.RunUnawaitedTask(SignalUpdateComplete);
                    }
                    catch (Exception ex)
                    {
                        CoreTaskHelper.RunUnawaitedTask(() => SignalUpdateError(ex));
                    }

                    return(Nothing.Value);
                }

                CoreTaskHelper.RunUnawaitedTaskAsync2(DoUpdate);
            }
            catch (Exception ex)
            {
                GlobalErrorHandler?.SignalError(ex);
            }
            return(Nothing.Value);
        }
Esempio n. 8
0
        /// <summary>
        /// ќдин раз вызвать инициализацию таблицы tableversion или ждать, если инициализаци¤ уже запущена.
        /// </summary>
        /// <param name="initFunc">‘ункци¤ инициализации.</param>
        public async Task InitializeTableVersionOnce(Func <ValueTask <Nothing> > initFunc)
        {
            if (initFunc == null)
            {
                throw new ArgumentNullException(nameof(initFunc));
            }
            if (Interlocked.Exchange(ref _isProcessing, 1) == 0)
            {
                try
                {
                    await CoreTaskHelper.RunAsyncFuncOnNewThreadValueTask(initFunc);

                    _tcs.SetResult(Nothing.Value);
                }
                catch (Exception ex)
                {
                    _tcs.SetException(ex);
                }
            }
            else
            {
                await _task;
            }
        }
Esempio n. 9
0
 private async Task <Nothing> CloseFile(string tmpName)
 {
     return(await CoreTaskHelper.RunAsyncFuncOnNewThread(async() =>
     {
         var tempFile2 = await ApplicationData.Current.TemporaryFolder.GetFileAsync(tmpName);
         if (_moveToFolder != null && !string.IsNullOrWhiteSpace(_moveToFileName))
         {
             try
             {
                 await tempFile2.MoveAsync(_moveToFolder, _moveToFileName, NameCollisionOption.ReplaceExisting);
             }
             catch
             {
                 await tempFile2.DeleteAsync();
                 throw;
             }
         }
         else
         {
             await tempFile2.DeleteAsync();
         }
         return Nothing.Value;
     }));
 }
Esempio n. 10
0
        public async Task BoardReferenceParallelQuery()
        {
            var boards = await TestResources.LoadBoardReferencesFromResource();

            var parser = _provider.FindNetworkDtoParser <MobileBoardInfoCollection, IList <IBoardReference> >();
            var result = parser.Parse(boards);
            await _store.UpdateReferences(result, true);

            async Task <Nothing> Query(int cid, int qid)
            {
                Logger.LogMessage($"Query {cid}:{qid} started");
                var links = result.Take(40).Select(r => r.BoardLink);

                foreach (var l in links)
                {
                    var o = await _store.LoadReference(l);

                    Assert.IsNotNull(o, "Не получена информация о доске");
                    Assert.IsTrue(BoardLinkEqualityComparer.Instance.Equals(l, o.BoardLink), "Ссылка не соответствует исходной");
                }
                Logger.LogMessage($"Query {cid}:{qid} finished");
                return(Nothing.Value);
            }

            for (var i = 0; i < 5; i++)
            {
                Logger.LogMessage($"Cycle {i} started");
                await _collection.Suspend();

                Logger.LogMessage("DB suspended");
                await _collection.Resume();

                Logger.LogMessage("DB resumed");
                var cid    = i;
                var toWait = new Task[]
                {
                    CoreTaskHelper.RunAsyncFuncOnNewThread(() => Query(cid, 1)),
                    CoreTaskHelper.RunAsyncFuncOnNewThread(() => Query(cid, 2)),
                    CoreTaskHelper.RunAsyncFuncOnNewThread(() => Query(cid, 3)),
                    CoreTaskHelper.RunAsyncFuncOnNewThread(() => Query(cid, 4)),
                    CoreTaskHelper.RunAsyncFuncOnNewThread(() => Query(cid, 5)),
                    CoreTaskHelper.RunAsyncFuncOnNewThread(() => Query(cid, 6)),
                    CoreTaskHelper.RunAsyncFuncOnNewThread(() => Query(cid, 7)),
                    CoreTaskHelper.RunAsyncFuncOnNewThread(() => Query(cid, 8)),
                    CoreTaskHelper.RunAsyncFuncOnNewThread(() => Query(cid, 9)),
                    CoreTaskHelper.RunAsyncFuncOnNewThread(() => Query(cid, 10)),
                    CoreTaskHelper.RunAsyncFuncOnNewThread(() => Query(cid, 11)),
                    CoreTaskHelper.RunAsyncFuncOnNewThread(() => Query(cid, 12)),
                    CoreTaskHelper.RunAsyncFuncOnNewThread(() => Query(cid, 13)),
                    CoreTaskHelper.RunAsyncFuncOnNewThread(() => Query(cid, 14)),
                    CoreTaskHelper.RunAsyncFuncOnNewThread(() => Query(cid, 15)),
                    CoreTaskHelper.RunAsyncFuncOnNewThread(() => Query(cid, 16)),
                    CoreTaskHelper.RunAsyncFuncOnNewThread(() => Query(cid, 17)),
                    CoreTaskHelper.RunAsyncFuncOnNewThread(() => Query(cid, 18)),
                    CoreTaskHelper.RunAsyncFuncOnNewThread(() => Query(cid, 19)),
                    CoreTaskHelper.RunAsyncFuncOnNewThread(() => Query(cid, 20)),
                    CoreTaskHelper.RunAsyncFuncOnNewThread(() => Query(cid, 21)),
                    CoreTaskHelper.RunAsyncFuncOnNewThread(() => Query(cid, 22)),
                    CoreTaskHelper.RunAsyncFuncOnNewThread(() => Query(cid, 23)),
                    CoreTaskHelper.RunAsyncFuncOnNewThread(() => Query(cid, 24)),
                    CoreTaskHelper.RunAsyncFuncOnNewThread(() => Query(cid, 25)),
                    CoreTaskHelper.RunAsyncFuncOnNewThread(() => Query(cid, 26)),
                    CoreTaskHelper.RunAsyncFuncOnNewThread(() => Query(cid, 27)),
                    CoreTaskHelper.RunAsyncFuncOnNewThread(() => Query(cid, 28)),
                    CoreTaskHelper.RunAsyncFuncOnNewThread(() => Query(cid, 29)),
                    CoreTaskHelper.RunAsyncFuncOnNewThread(() => Query(cid, 30)),
                };

                Logger.LogMessage($"Waiting for all queries (cycle {i})");
                await Task.WhenAll(toWait);

                Logger.LogMessage($"Waited for all queries (cycle {i})");
            }
        }
            public async ValueTask <(IEsentSession session, IDisposable disposable)> GetAvailableSession(bool autoUse)
            {
                async Task <Nothing> DoDisposeExccessSessions()
                {
                    async Task DoDispose(EsentSession s)
                    {
                        try
                        {
                            await s.DisposeInternal();
                        }
                        catch
                        {
                            // Игнорируем ошибки
                        }
                    }

                    List <EsentSession> toDispose = new List <EsentSession>();

                    lock (Waiters.UsingLock)
                    {
                        var allSessions  = _readonlySessions.Count;
                        var freeSessions = _readonlySessions.Where(s => s.UsingsCount == 0).ToArray();
                        if (allSessions > MaxReserveSessionsCount)
                        {
                            toDispose.AddRange(freeSessions.Skip(ReserveSessionsCount));
                        }
                        foreach (var s in toDispose)
                        {
                            _readonlySessions.Remove(s);
                        }
                    }
                    if (toDispose.Count > 0)
                    {
                        var t1 = Task.WhenAll(toDispose.Select(DoDispose));
                        var t2 = Task.Delay(TimeSpan.FromSeconds(15));
                        await Task.WhenAny(t1, t2);
                    }
                    return(Nothing.Value);
                }

                lock (Waiters.UsingLock)
                {
                    var freeSessions = _readonlySessions.Where(s => s.UsingsCount == 0).ToArray();
                    if (freeSessions.Length > 0)
                    {
                        EsentSession r;
                        IDisposable  d = null;
                        if (freeSessions.Length == 1)
                        {
                            r = freeSessions[0];
                        }
                        else
                        {
                            r = freeSessions[_rnd.Next(0, freeSessions.Length)];
                        }
                        if (autoUse)
                        {
                            r.UsingsCount++;
                            d = r.CreateUsageDisposable();
                        }
                        return(r, d);
                    }
                }
                var newSession = await EsentSession.CreateReadOnlySession(MainSession, Waiters);

                IDisposable d2 = null;

                lock (Waiters.UsingLock)
                {
                    _readonlySessions.Add(newSession);
                    if (autoUse)
                    {
                        newSession.UsingsCount++;
                        d2 = newSession.CreateUsageDisposable();
                    }
                }
                CoreTaskHelper.RunUnawaitedTaskAsync(DoDisposeExccessSessions);
                return(newSession, d2);
            }
Esempio n. 12
0
        private async ValueTask <Nothing> SetChildren(IBoardPostEntity entity)
        {
            if (entity == null)
            {
                return(Nothing.Value);
            }

            ValueTask <List <IBoardPostEntity> > DoLoad(IList <(PostStoreEntityId id, int counter)> toLoad)
            {
                return(OpenSession(session =>
                {
                    var result = new List <IBoardPostEntity>();
                    var loadContext = CreateLoadContext(session, true, true);
                    var loadContextToDispose = loadContext;
                    using (loadContextToDispose)
                    {
                        foreach (var id in toLoad)
                        {
                            Api.MakeKey(loadContext.table.Session, loadContext.table, id.id.Id, MakeKeyGrbit.NewKey);
                            if (Api.TrySeek(loadContext.table.Session, loadContext.table, SeekGrbit.SeekEQ))
                            {
                                var r = LoadBoardEntity(session, ref loadContext, FullLoadMode);
                                if (r is IBoardPostLight l)
                                {
                                    l.Counter = id.counter;
                                }
                                result.Add(r);
                            }
                        }
                    }
                    return result;
                }));
            }

            var collection       = entity as IBoardPostCollection;
            var threadCollection = entity as IBoardPageThreadCollection;

            if ((entity.EntityType == PostStoreEntityType.Thread || entity.EntityType == PostStoreEntityType.ThreadPreview || entity.EntityType == PostStoreEntityType.Catalog || entity.EntityType == PostStoreEntityType.BoardPage) &&
                entity is IPostModelStoreChildrenLoadStageInfo loadStage && (collection?.Posts != null || threadCollection?.Threads != null) &&
                entity.StoreId != null)
            {
                if (loadStage.Stage == ChildrenLoadStageId.Completed)
                {
                    var childrenIds = await OpenSession(session0 => EnumEntityChildren(session0, entity.StoreId.Value));

                    IList <IBoardPostEntity> loaded;
                    if (childrenIds.Count > 4)
                    {
                        var toLoad      = childrenIds.DistributeToProcess(3);
                        var tasks       = toLoad.Select(DoLoad).ToArray();
                        var taskResults = await CoreTaskHelper.WhenAllValueTasks(tasks);

                        loaded = taskResults.SelectMany(r => r).ToList();
                    }
                    else
                    {
                        loaded = await DoLoad(childrenIds);
                    }

                    if (collection?.Posts != null)
                    {
                        IEnumerable <IBoardPost> toAdd;
                        if (entity.EntityType == PostStoreEntityType.Catalog)
                        {
                            int GetCatalogSequence(IBoardPost p)
                            {
                                if (p is IBoardPostEntityWithSequence s)
                                {
                                    return(s.OnPageSequence);
                                }
                                return(int.MaxValue);
                            }

                            toAdd = loaded.OfType <IBoardPost>().Deduplicate(p => p.Link, BoardLinkEqualityComparer.Instance).OrderBy(GetCatalogSequence);
                        }
                        else
                        {
                            toAdd = loaded.OfType <IBoardPost>().Deduplicate(p => p.Link, BoardLinkEqualityComparer.Instance).OrderBy(p => p.Link, BoardLinkComparer.Instance);
                        }
                        foreach (var item in toAdd)
                        {
                            collection.Posts.Add(item);
                        }
                    }
                    if (threadCollection?.Threads != null)
                    {
                        var toAdd = loaded.OfType <IThreadPreviewPostCollection>().Deduplicate(p => p.Link, BoardLinkEqualityComparer.Instance).OrderBy(p => p.OnPageSequence);
                        foreach (var item in toAdd)
                        {
                            threadCollection.Threads.Add(item);
                        }
                    }
                }
            }

            return(Nothing.Value);
        }