示例#1
0
        public IDisposable Connect()
        {
            lock (_gate)
            {
                if (_state != State.Unconnected)
                {
                    throw new Exception("Can't connect an already connected ReplayObservableList");
                }

                _state = State.Connected;

                var subscription = _source.Subscribe(
                    Observer.Create <ListChange <T> >(
                        onNext: change =>
                {
                    lock (_gate)
                    {
                        _value = change.Apply(_value);

                        foreach (var observer in _observers)
                        {
                            observer.OnNext(change);
                        }
                    }
                },
                        onError: error =>
                {
                    lock (_gate)
                    {
                        _state = State.Error;
                        _error = error;

                        foreach (var observer in _observers)
                        {
                            observer.OnError(error);
                        }
                        _observers = ImmutableList <IObserver <ListChange <T> > > .Empty;
                    }
                },
                        onCompleted: () =>
                {
                    lock (_gate)
                    {
                        _state = State.Completed;

                        foreach (var observer in _observers)
                        {
                            observer.OnCompleted();
                        }
                        _observers = ImmutableList <IObserver <ListChange <T> > > .Empty;
                    }
                }));

                return(Disposable.Combine(
                           subscription,
                           Disposable.Create(
                               () =>
                {
                    _state = State.Unconnected;
                    _value = ImmutableList <T> .Empty;
                    _observers = ImmutableList <IObserver <ListChange <T> > > .Empty;
                })));
            }
        }
示例#2
0
 internal static IDisposable OnSuroundOperation(IOperation operation, OperationLogEntity log, IEntity entity, object[] args)
 {
     return(Disposable.Combine(SurroundOperation, f => f(operation, log, (Entity)entity, args)));
 }
示例#3
0
 public static IDisposable?OnApplySession(ProcessEntity process)
 {
     return(Disposable.Combine(ApplySession, f => f(process)));
 }
        public static Pop3ReceptionEntity ReceiveEmailsFullComparation(this Pop3ConfigurationEntity config)
        {
            if (!EmailLogic.Configuration.ReciveEmails)
            {
                throw new InvalidOperationException("EmailLogic.Configuration.ReciveEmails is set to false");
            }

            using (HeavyProfiler.Log("ReciveEmails"))
                using (Disposable.Combine(SurroundReceiveEmail, func => func(config)))
                {
                    Pop3ReceptionEntity reception = Transaction.ForceNew().Using(tr => tr.Commit(
                                                                                     new Pop3ReceptionEntity {
                        Pop3Configuration = config.ToLite(), StartDate = TimeZoneManager.Now
                    }.Save()));

                    var now = TimeZoneManager.Now;
                    try
                    {
                        using (var client = GetPop3Client(config))
                        {
                            var messageInfos = client.GetMessageInfos();

                            var already = messageInfos.Select(a => a.Uid).GroupsOf(50).SelectMany(l =>
                                                                                                  (from em in Database.Query <EmailMessageEntity>()
                                                                                                   let ri = em.Mixin <EmailReceptionMixin>().ReceptionInfo
                                                                                                            where ri != null && l.Contains(ri.UniqueId)
                                                                                                            select KVP.Create(ri.UniqueId, (DateTime?)ri.SentDate))).ToDictionary();

                            using (Transaction tr = Transaction.ForceNew())
                            {
                                reception.NewEmails = messageInfos.Count - already.Count;
                                reception.Save();
                                tr.Commit();
                            }

                            foreach (var mi in messageInfos)
                            {
                                var sent = already.TryGetS(mi.Uid);

                                if (sent == null)
                                {
                                    sent = SaveEmail(config, reception, client, mi);
                                }

                                DeleteSavedEmail(config, now, client, mi, sent);
                            }

                            using (Transaction tr = Transaction.ForceNew())
                            {
                                reception.EndDate = TimeZoneManager.Now;
                                reception.Save();
                                tr.Commit();
                            }

                            client.Disconnect(); //Delete messages now
                        }
                    }
                    catch (Exception e)
                    {
                        var ex = e.LogException();

                        try
                        {
                            using (Transaction tr = Transaction.ForceNew())
                            {
                                reception.EndDate   = TimeZoneManager.Now;
                                reception.Exception = ex.ToLite();
                                reception.Save();
                                tr.Commit();
                            }
                        }
                        catch { }
                    }

                    ReceptionComunication?.Invoke(reception);

                    return(reception);
                }
        }
        public static Pop3ReceptionEntity ReceiveEmailsPartialComparation(this Pop3ConfigurationEntity config)
        {
            if (!EmailLogic.Configuration.ReciveEmails)
            {
                throw new InvalidOperationException("EmailLogic.Configuration.ReciveEmails is set to false");
            }

            using (HeavyProfiler.Log("ReciveEmails"))
                using (Disposable.Combine(SurroundReceiveEmail, func => func(config)))
                {
                    Pop3ReceptionEntity reception = Transaction.ForceNew().Using(tr => tr.Commit(
                                                                                     new Pop3ReceptionEntity {
                        Pop3Configuration = config.ToLite(), StartDate = TimeZoneManager.Now
                    }.Save()));

                    var now = TimeZoneManager.Now;
                    try
                    {
                        using (var client = GetPop3Client(config))
                        {
                            var messageInfos = client.GetMessageInfos().OrderBy(m => m.Number);


                            var lastsEmails = Database.Query <EmailMessageEntity>()
                                              .Where(e => e.Mixin <EmailReceptionMixin>().ReceptionInfo.Reception.Entity.Pop3Configuration.RefersTo(config))
                                              .Select(d => new { d.CreationDate, d.Mixin <EmailReceptionMixin>().ReceptionInfo.UniqueId })
                                              .OrderByDescending(c => c.CreationDate).Take(10).ToDictionary(e => e.UniqueId);


                            List <MessageUid> messagesToSave;
                            if (lastsEmails.Any())
                            {
                                var messageJoinDict = messageInfos.ToDictionary(e => e.Uid).OuterJoinDictionarySC(lastsEmails, (key, v1, v2) => new { key, v1, v2 });
                                var messageMachings = messageJoinDict.Where(e => e.Value.v1 != null && e.Value.v2 != null).ToList();
                                messagesToSave = !messageMachings.Any()? messageInfos.ToList(): messageInfos.Where(m => m.Number > messageMachings.Select(e => e.Value.v1.Value.Number).Max()).ToList();
                            }
                            else
                            {
                                messagesToSave = messageInfos.ToList();
                            }

                            using (Transaction tr = Transaction.ForceNew())
                            {
                                reception.NewEmails = messagesToSave.Count;
                                reception.Save();
                                tr.Commit();
                            }

                            foreach (var mi in messagesToSave)
                            {
                                var sent = SaveEmail(config, reception, client, mi);

                                DeleteSavedEmail(config, now, client, mi, sent);
                            }

                            using (Transaction tr = Transaction.ForceNew())
                            {
                                reception.EndDate = TimeZoneManager.Now;
                                reception.Save();
                                tr.Commit();
                            }

                            client.Disconnect(); //Delete messages now
                        }
                    }
                    catch (Exception e)
                    {
                        var ex = e.LogException();

                        try
                        {
                            using (Transaction tr = Transaction.ForceNew())
                            {
                                reception.EndDate   = TimeZoneManager.Now;
                                reception.Exception = ex.ToLite();
                                reception.Save();
                                tr.Commit();
                            }
                        }
                        catch { }
                    }

                    ReceptionComunication?.Invoke(reception);

                    return(reception);
                }
        }
示例#6
0
        public static LiveDocument Open(
            AbsoluteFilePath path,
            IFileSystem fs,
            IObservable <ILookup <ObjectIdentifier, ObjectIdentifier> > metadata,
            BehaviorSubject <Dictionary <ObjectIdentifier, IElement> > idToElement,
            IObserver <IBinaryMessage> mutations,
            IScheduler scheduler)
        {
            IDocument <byte[]> fileOnDisk = new FileWatchingDocument(fs, path);


            var parsingErrors = new BehaviorSubject <Optional <Exception> >(Optional.None());

            var invalidated = new Subject <Unit>();

            var root = new LiveElement(
                file: path,
                metadata: metadata,
                isReadOnly: fileOnDisk.ErrorsDuringLoading.Or(parsingErrors)
                .Select(e => e.HasValue)
                .DistinctUntilChanged()
                .Replay(1).RefCount(),
                invalidated: invalidated,
                mutations: mutations,
                getElement: id =>
                idToElement.Value.TryGetValue(id).Or(Element.Empty));

            Optional <XElement> xElementForSaving = Optional.None <XElement>();

            var allElements = root.Subtree().Replay(1);

            var source = new ReplaySubject <SourceFragment>(1);

            return(new LiveDocument
            {
                _garbage = Disposable.Combine(

                    // Save on internal changes
                    invalidated
                    .Select(_ =>
                {
                    if (xElementForSaving.HasValue)
                    {
                        var sourceFragment = SourceFragment.FromXml(xElementForSaving.Value);
                        source.OnNext(sourceFragment);
                        return Optional.Some(sourceFragment);
                    }
                    return Optional.None();
                })
                    .NotNone()
                    .Throttle(TimeSpan.FromSeconds(0.5), scheduler)
                    .Select(sourceFragment =>
                            Observable.FromAsync(async() =>
                                                 await fileOnDisk.Save(sourceFragment.ToBytes())))
                    .Concat()
                    .Subscribe(),

                    // Load on external changes
                    fileOnDisk.ExternalChanges
                    .ObserveOn(Application.MainThread)
                    .Subscribe(reload =>
                {
                    var sourceFragment = SourceFragment.FromBytes(reload);
                    source.OnNext(sourceFragment);

                    try
                    {
                        var simulatorWasFaulted = parsingErrors.Value.HasValue;

                        var newDocument = sourceFragment.ToXml();
                        parsingErrors.OnNext(Optional.None());

                        xElementForSaving = Optional.None();
                        Console.WriteLine("Reloading " + path + " from disk...");
                        root.UpdateFrom(newDocument);                                                 // no known reasons to throw
                        xElementForSaving = Optional.Some(newDocument);

                        // hack to clear errors from the simulator,
                        // since UpdateFrom() doesn't know that the simulator
                        // have failed and will try to emit incremental updates
                        if (simulatorWasFaulted)
                        {
                            mutations.OnNext(new ReifyRequired());
                        }
                    }
                    catch (Exception e)
                    {
                        parsingErrors.OnNext(e);

                        // hack to get errors from the simulator
                        mutations.OnNext(new ReifyRequired());
                    }
                }),

                    // Share subscription to Eleements
                    allElements.Connect(),

                    // Dispose fileOnDisk when disposed
                    fileOnDisk),

                FilePath = Observable.Return(path),

                Errors = fileOnDisk.Errors.Or(parsingErrors),

                SimulatorIdPrefix = path.NativePath,

                Source = source,

                Root = root,
                Elements = allElements,

                _root = root,
                _path = path,
                _idToElement = idToElement,
            });
        }