Beispiel #1
0
 public RemoteSession(RemoteSessionContructorOptions options)
 {
     options.Validate();
     _workExecutor            = options.WorkExecutor ?? new TaskFactory(TaskScheduler.Default);
     _cancellationTokenSource = options.CancellationTokenSource == null ? new CancellationTokenSource() : CancellationTokenSource.CreateLinkedTokenSource(options.CancellationTokenSource.Token);
     _id      = options.Id;
     _baseUrl = options.BaseUrl;
 }
 public RemoteSession(RemoteSessionContructorOptions options)
 {
     options.Validate();
     _workExecutor = options.WorkExecutor ?? new TaskFactory(TaskScheduler.Default);
     _cancellationTokenSource = options.CancellationTokenSource == null ? new CancellationTokenSource() : CancellationTokenSource.CreateLinkedTokenSource(options.CancellationTokenSource.Token);
     _id = options.Id;
     _baseUrl = options.BaseUrl;
 }
        /// <summary>
        /// Default constructor
        /// </summary>
        /// <param name="db">The local database to replicate to/from</param>
        /// <param name="remote">The remote Uri to sync with</param>
        /// <param name="continuous">If set to <c>true</c> continuous.</param>
        /// <param name="clientFactory">The client factory for instantiating the HttpClient used to create web requests</param>
        /// <param name="workExecutor">The TaskFactory to execute work on</param>
        internal Replication(Database db, Uri remote, bool continuous, IHttpClientFactory clientFactory, TaskFactory workExecutor)
        {
            sessionID = $"repl{ Interlocked.Increment(ref _lastSessionID):000}";
            var opts = new RemoteSessionContructorOptions {
                BaseUrl = remote,
                WorkExecutor = workExecutor,
                Id = _replicatorID,
                CancellationTokenSource = CancellationTokenSource
            };
            _remoteSession = new RemoteSession(opts);
            Username = remote.UserInfo;

            LocalDatabase = db;
            _eventContext = LocalDatabase.Manager.CapturedContext;
            Continuous = continuous;
            // NOTE: Consider running a separate scheduler for all http requests.
            WorkExecutor = workExecutor;
            RemoteUrl = remote;
#pragma warning disable 618
            Options = new ReplicationOptionsDictionary();
#pragma warning restore 618
            ReplicationOptions = new ReplicationOptions();

            if (RemoteUrl.Query != null && !StringEx.IsNullOrWhiteSpace(RemoteUrl.Query)) {
                Authenticator = AuthenticatorFactory.CreateFromUri(remote);

                // we need to remove the query from the URL, since it will cause problems when
                // communicating with sync gw / couchdb
                try {
                    RemoteUrl = new UriBuilder(remote.Scheme, remote.Host, remote.Port, remote.AbsolutePath).Uri;
                } catch (UriFormatException e) {
                    throw Misc.CreateExceptionAndLog(Log.To.Sync, e, Tag,
                        "Invalid URI format for remote endpoint");
                }
            }

            Batcher = new Batcher<RevisionInternal>(workExecutor, INBOX_CAPACITY, ProcessorDelay, inbox =>
            {
                try {
                    Log.To.Sync.V(Tag, "*** {0} BEGIN ProcessInbox ({1} sequences)", this, inbox.Count);
                    if(Continuous) {
                        FireTrigger(ReplicationTrigger.Resume);
                    }

                    ProcessInbox (new RevisionList(inbox));

                    Log.To.Sync.V(Tag, "*** {0} END ProcessInbox (lastSequence={1})", this, LastSequence);
                } catch(Exception e) {
                    throw Misc.CreateExceptionAndLog(Log.To.Sync, e, Tag, 
                        "{0} ProcessInbox failed", this);
                }
            });

            ClientFactory = clientFactory;

            _stateMachine = new StateMachine<ReplicationState, ReplicationTrigger>(ReplicationState.Initial);
            InitializeStateMachine();
        }