public IObservableWithTask <IndexChangeNotification> ForIndex(string indexName) { var counter = counters.GetOrAdd("indexes/" + indexName, s => { var indexSubscriptionTask = AfterConnection(() => { watchedIndexes.TryAdd(indexName); return(Send("watch-index", indexName)); }); return(new LocalConnectionState( () => { watchedIndexes.TryRemove(indexName); Send("unwatch-index", indexName); counters.Remove("indexes/" + indexName); }, indexSubscriptionTask)); }); counter.Inc(); var taskedObservable = new TaskedObservable <IndexChangeNotification>( counter, notification => string.Equals(notification.Name, indexName, StringComparison.InvariantCultureIgnoreCase)); counter.OnIndexChangeNotification += taskedObservable.Send; counter.OnError = taskedObservable.Error; return(taskedObservable); }
public IObservable <ConfigChange> ConfigurationChanges() { EnsureConnectionInitiated(); #pragma warning disable 4014 var observable = subjects.GetOrAdd("config", s => new NotificationSubject <ConfigChange>( () => ConfigureConnection("watch-config"), () => ConfigureConnection("unwatch-config"), item => true)); #pragma warning restore 4014 return((IObservable <ConfigChange>)observable); }
public IObservableWithTask <IndexChangeNotification> ForIndex(string indexName) { var counter = counters.GetOrAdd("indexes/" + indexName, s => { var indexSubscriptionTask = AfterConnection(() => { connectionsData.AddOrUpdate("watch-index", indexName, (s1, s2) => s2); return(Send("watch-index", indexName)); }); return(new LocalConnectionState( () => { string value; connectionsData.TryRemove("watch-index", out value); Send("unwatch-index", indexName); counters.Remove("indexes/" + indexName); }, indexSubscriptionTask)); }); counter.Inc(); var taskedObservable = new TaskedObservable <IndexChangeNotification>( counter, notification => string.Equals(notification.Name, indexName, StringComparison.InvariantCultureIgnoreCase)); counter.OnIndexChangeNotification += taskedObservable.Send; counter.OnError = taskedObservable.Error; var disposableTask = counter.Task.ContinueWith(task => { if (task.IsFaulted) { return(null); } return((IDisposable) new DisposableAction(() => { try { connection.Dispose(); } catch (Exception) { // nothing to do here } })); }); counter.Add(disposableTask); return(taskedObservable); }
protected virtual IFilesChanges CreateFileSystemChanges(string filesystem) { if (string.IsNullOrEmpty(Url)) { throw new InvalidOperationException("Changes API requires usage of server/client"); } var tenantUrl = Url + "/fs/" + filesystem; var commands = fileSystemCommands.GetOrAdd(filesystem, x => (IAsyncFilesCommandsImpl)this.AsyncFilesCommands.ForFileSystem(x)); using (NoSynchronizationContext.Scope()) { var client = new FilesChangesClient(tenantUrl, ApiKey, Credentials, jsonRequestFactory, Conventions, commands.ReplicationInformer, ((AsyncFilesServerClient)this.AsyncFilesCommands).TryResolveConflictByUsingRegisteredListenersAsync, () => { fileSystemChanges.Remove(filesystem); fileSystemCommands.Remove(filesystem); }); return(client); } }
/// <summary> /// Subscribe to change notifications from the server /// </summary> public override IDatabaseChanges Changes(string database = null) { AssertInitialized(); return(databaseChanges.GetOrAdd(database ?? DefaultDatabase, CreateDatabaseChanges)); }
public IFilesChanges Changes(string filesystem = null) { AssertInitialized(); if (string.IsNullOrWhiteSpace(filesystem)) { filesystem = this.DefaultFileSystem; } return(fileSystemChanges.GetOrAdd(filesystem, CreateFileSystemChanges)); }
public ICountersChanges Changes(string counterStorage = null) { AssertInitialized(); if (string.IsNullOrWhiteSpace(counterStorage)) { counterStorage = Name; } return(counterStorageChanges.GetOrAdd(counterStorage, CreateCounterStorageChanges)); }
public ITimeSeriesChanges Changes(string timeSeries = null) { AssertInitialized(); if (string.IsNullOrWhiteSpace(timeSeries)) { timeSeries = Name; } return(timeSeriesChanges.GetOrAdd(timeSeries, CreateTimeSeriesChanges)); }
protected TConnectionState GetOrAddConnectionState(string name, string watchCommand, string unwatchCommand, Action afterConnection, Action beforeDisconnect, string value) { var counter = Counters.GetOrAdd(name, s => { Func <Task> onZero = () => { beforeDisconnect(); Counters.Remove(name); return(Send(unwatchCommand, value)); }; Func <TConnectionState, Task> ensureConnection = existingConnectionState => { TConnectionState _; if (Counters.TryGetValue(name, out _)) { return(_.Task); } Counters.GetOrAdd(name, x => existingConnectionState); return(AfterConnection(() => { afterConnection(); return Send(watchCommand, value); })); }; var counterSubscriptionTask = AfterConnection(() => { afterConnection(); return(Send(watchCommand, value)); }); return(CreateTConnectionState(onZero, ensureConnection, counterSubscriptionTask)); }); return(counter); }
protected bool TryGetOrCreateResourceStore(string tenantId, out Task <DocumentDatabase> database) { if (ResourcesStoresCache.TryGetValue(tenantId, out database)) { if (database.IsFaulted || database.IsCanceled) { ResourcesStoresCache.TryRemove(tenantId, out database); DateTime time; databaseLastRecentlyUsed.TryRemove(tenantId, out time); // and now we will try creating it again } else { return(true); } } if (LockedDatabases.Contains(tenantId)) { throw new InvalidOperationException("Database '" + tenantId + "' is currently locked and cannot be accessed"); } var config = CreateTenantConfiguration(tenantId); if (config == null) { return(false); } database = ResourcesStoresCache.GetOrAdd(tenantId, __ => Task.Factory.StartNew(() => { var documentDatabase = new DocumentDatabase(config); AssertLicenseParameters(config); documentDatabase.SpinBackgroundWorkers(); InitializeRequestResponders(documentDatabase); // if we have a very long init process, make sure that we reset the last idle time for this db. databaseLastRecentlyUsed.AddOrUpdate(tenantId, SystemTime.UtcNow, (_, time) => SystemTime.UtcNow); return(documentDatabase); }).ContinueWith(task => { if (task.Status == TaskStatus.Faulted) // this observes the task exception { logger.WarnException("Failed to create database " + tenantId, task.Exception); } return(task); }).Unwrap()); return(true); }
private DatabaseConnectionState GetOrAddConnectionState(string name, string watchCommand, string unwatchCommand, string value) { var counter = _counters.GetOrAdd(name, s => { async Task OnDisconnect() { try { if (Connected) { await Send(unwatchCommand, value).ConfigureAwait(false); } } catch (WebSocketException) { // if we are not connected then we unsubscribed already // because connections drops with all subscriptions } DatabaseConnectionState state; if (_counters.TryRemove(s, out state)) { state.Dispose(); } } async Task <bool> OnConnect() { try { if (Connected) { await Send(watchCommand, value).ConfigureAwait(false); return(true); } } catch (WebSocketException) { // if we are not connected then we will subscribe again after connection be established } return(false); } return(new DatabaseConnectionState(this, OnConnect, OnDisconnect)); }); return(counter); }
public void Repeat(IRepeatedAction action) { var tuple = timers.GetOrAdd(action.RepeatDuration.ToString(), span => { var repeatedActions = new ConcurrentSet <IRepeatedAction> { action }; var timer = new Timer(ExecuteTimer, action.RepeatDuration, action.RepeatDuration, action.RepeatDuration); return(Tuple.Create(timer, repeatedActions)); }); tuple.Item2.TryAdd(action); }
private DatabaseConnectionState GetOrAddConnectionState(string name, string watchCommand, string unwatchCommand, string value) { bool newValue = false; var counter = _counters.GetOrAdd(name, s => { async Task OnDisconnect() { try { if (Connected) { await Send(unwatchCommand, value).ConfigureAwait(false); } } catch (WebSocketException) { // if we are not connected then we unsubscribed already // because connections drops with all subscriptions } if (_counters.TryRemove(s, out var state)) { state.Dispose(); } } async Task OnConnect() { await Send(watchCommand, value).ConfigureAwait(false); } newValue = true; return(new DatabaseConnectionState(OnConnect, OnDisconnect)); }); // try to reconnect if (newValue && Volatile.Read(ref _immediateConnection) != 0) { counter.Set(counter.OnConnect()); } return(counter); }
public override IDatabaseChanges Changes(string database = null) { return(changes.GetOrAdd(database, _ => new ShardedDatabaseChanges(ShardStrategy.Shards.Values.Select(x => x.Changes(database)).ToArray()))); }