/// <summary> /// add node to the map /// return true if the node is added; false otherwise. /// </summary> internal virtual bool Add(DatanodeDescriptor node) { hostmapLock.WriteLock().Lock(); try { if (node == null || Contains(node)) { return(false); } string ipAddr = node.GetIpAddr(); string hostname = node.GetHostName(); mapHost[hostname] = ipAddr; DatanodeDescriptor[] nodes = map[ipAddr]; DatanodeDescriptor[] newNodes; if (nodes == null) { newNodes = new DatanodeDescriptor[1]; newNodes[0] = node; } else { // rare case: more than one datanode on the host newNodes = new DatanodeDescriptor[nodes.Length + 1]; System.Array.Copy(nodes, 0, newNodes, 0, nodes.Length); newNodes[nodes.Length] = node; } map[ipAddr] = newNodes; return(true); } finally { hostmapLock.WriteLock().Unlock(); } }
/// <summary> /// Proceeds a lookup into current AppDomain to detect functions marked as exported /// and available to be remote executed /// </summary> public static void Register() { #if NET_FRAMEWORK foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies()) #else foreach (Assembly assembly in AssemblyLoadContext.Default.Assemblies) #endif { foreach (Type type in assembly.GetTypes()) { foreach (MethodInfo remoteProcedure in type.GetMethods <ExportEndPointAttribute>(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static)) { string remoteId = string.Concat(type.FullName, ".", remoteProcedure.Name); registryLock.WriteLock(); try { if (!registry.ContainsKey(remoteId)) { ParameterInfo[] parameter = remoteProcedure.GetParameters(); bool extend; if (parameter.Length > 0) { extend = (parameter[0].ParameterType.IsAssignableFrom(PeerInterfaceType)); } else { extend = false; } Func <object[], object> target = remoteProcedure.CreateDelegate().DynamicInvoke; Action <IMessageSource, IMessage> action; if (TaskType.IsAssignableFrom(remoteProcedure.ReturnType)) { action = (remoteHost, message) => { CallAsync(remoteHost, message, target, extend); }; } else { action = (remoteHost, message) => { Call(remoteHost, message, target, extend); } }; registry.Add(remoteId, action); } else { Application.Warning(SeverityFlags.Full, "End point '{0}' already defined", remoteId); } } finally { registryLock.WriteRelease(); } } } } }
/// <summary> /// Add a leaf node /// Update node counter & rack counter if necessary /// </summary> /// <param name="node">node to be added; can be null</param> /// <exception> /// IllegalArgumentException /// if add a node to a leave /// or node to be added is not a leaf /// </exception> public virtual void Add(Node node) { if (node == null) { return; } int newDepth = NodeBase.LocationToDepth(node.GetNetworkLocation()) + 1; netlock.WriteLock().Lock(); try { string oldTopoStr = this.ToString(); if (node is NetworkTopology.InnerNode) { throw new ArgumentException("Not allow to add an inner node: " + NodeBase.GetPath (node)); } if ((depthOfAllLeaves != -1) && (depthOfAllLeaves != newDepth)) { Log.Error("Error: can't add leaf node " + NodeBase.GetPath(node) + " at depth " + newDepth + " to topology:\n" + oldTopoStr); throw new NetworkTopology.InvalidTopologyException("Failed to add " + NodeBase.GetPath (node) + ": You cannot have a rack and a non-rack node at the same " + "level of the network topology." ); } Node rack = GetNodeForNetworkLocation(node); if (rack != null && !(rack is NetworkTopology.InnerNode)) { throw new ArgumentException("Unexpected data node " + node.ToString() + " at an illegal network location" ); } if (clusterMap.Add(node)) { Log.Info("Adding a new node: " + NodeBase.GetPath(node)); if (rack == null) { numOfRacks++; } if (!(node is NetworkTopology.InnerNode)) { if (depthOfAllLeaves == -1) { depthOfAllLeaves = node.GetLevel(); } } } if (Log.IsDebugEnabled()) { Log.Debug("NetworkTopology became:\n" + this.ToString()); } } finally { netlock.WriteLock().Unlock(); } }
public override bool TryGet(object[] parameter, out IReactiveStream <IMessage, bool> result) { if (parameter.Length == 0) { throw new IndexOutOfRangeException(); } if (!(parameter[0] is UInt32)) { throw new ArgumentOutOfRangeException("parameter"); } UInt32 id = (UInt32)parameter[0]; streamLock.WriteLock(); try { if (!streams.TryGetValue(id, out result)) { result = new MessageStream <IMessage> ( new PriorityDispatcher() ); streams.Add(id, result); } return(true); } finally { streamLock.WriteRelease(); } }
public void Register(IReceiver <IMessage, bool> observer) { IPrioritizedActor actor = observer as IPrioritizedActor; if (actor == null) { throw new ArgumentException(); } subscriptionLock.WriteLock(); try { subscriptions.Add(actor); Sort(); actor.Attach(this); } finally { subscriptionLock.WriteRelease(); } }
public Task UserLogoutAsync() { return(Task.Run(() => { using (ReadWriteLock.WriteLock()) { serversync = SyncState.Disabled; HttpClient.DefaultRequestHeaders.Authorization = null; last_sync = 0; App.Database.SaveVariable("authorization.credential", ""); App.Database.SaveVariable("last_sync", last_sync); } } )); }
public Task DelayedSyncAsync(int timeout) { return(Task.Run(() => { using (ReadWriteLock.WriteLock()) { //console.log("delayedsync: timeout = %i", timeout); var now = DateTime.UtcNow.Ticks / 10000; if (DelayedSyncCTS != null) { //console.log("delayedsync: existing pending sync in %i", no_sync_until - now); // If the pending sync is going to happen before timeout would elapse, just let it happen if (no_sync_until <= now + timeout) { return; } DelayedSyncCTS.Cancel(); DelayedSyncCTS = null; } //console.log("delayedsync: setting up timeout callback"); no_sync_until = now + timeout; serversync = SyncState.Delayed; var cts = DelayedSyncCTS = new CancellationTokenSource(); Task.Delay(timeout, DelayedSyncCTS.Token).ContinueWith(task => { using (ReadWriteLock.WriteLock()) { cts.Dispose(); if (cts == DelayedSyncCTS) { DelayedSyncCTS = null; } if (task.IsCompleted && serversync != SyncState.Syncing) { DoSyncAsync(true); } } }); } })); }
private Task <Dictionary <string, string> > UserLoginOrCreateAsync(string username, string password, string email) { return(Task.Run(() => { using (ReadWriteLock.WriteLock()) { serversync = SyncState.Disabled; HttpClient.DefaultRequestHeaders.Authorization = null; App.Database.SaveVariable("authorization.credential", ""); Task <HttpResponseMessage> responseTask; if (email == null) { var json = JsonConvert.SerializeObject(new { username = username, password = password }); var postBody = new StringContent(json, System.Text.Encoding.UTF8, "application/json"); responseTask = HttpClient.PostAsync(new Uri(url_base, "User/Login"), postBody); } else { var json = JsonConvert.SerializeObject(new { username = username, password = password, email = email }); var postBody = new StringContent(json, System.Text.Encoding.UTF8, "application/json"); responseTask = HttpClient.PostAsync(new Uri(url_base, "User/Create"), postBody); } responseTask.TryWait(); if (responseTask.IsFaulted) { return new Dictionary <string, string> { { "exception", responseTask.Exception.Message } }; } var response = responseTask.Result; if (!response.IsSuccessStatusCode) { return new Dictionary <string, string> { { "server", response.ReasonPhrase } }; } var contentTask = response.Content.ReadAsStringAsync(); contentTask.Wait(); var content = contentTask.Result; try { if (content.StartsWith("{")) { return JsonConvert.DeserializeObject <Dictionary <string, string> >(content); } string cred = JsonConvert.DeserializeObject <string>(content); Authorization authorization; authorization.credential = cred; authorization.username = username; HttpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Ao3track", authorization.ToBase64()); last_sync = 0; App.Database.SaveVariable("authorization.username", authorization.username); App.Database.SaveVariable("authorization.credential", authorization.credential); App.Database.SaveVariable("last_sync", last_sync); serversync = SyncState.Syncing; DoSyncAsync(true); } catch (Exception e) { App.Log(e); return new Dictionary <string, string> { { "exception", e.Message } }; } return null; } })); }
public Task SetWorkChaptersAsync(IDictionary <long, WorkChapter> works) { return(Task.Run(() => { using (ReadWriteLock.WriteLock()) { long time = DateTime.UtcNow.ToUnixTime(); Dictionary <long, Work> newitems = new Dictionary <long, Work>(); bool do_delayed = false; foreach (var work in works) { if (work.Value.workid == 0) { work.Value.workid = work.Key; } else if (work.Value.workid != work.Key) { throw new ArgumentException("Value.workid != Key", nameof(works)); } if (!storage.TryGetValue(work.Key, out var old) || old.LessThan(work.Value)) { var seq = work.Value.seq; if (seq == null && old != null) { seq = old.Seq; } var w = new Work { workid = work.Key, number = work.Value.number, chapterid = work.Value.chapterid, location = work.Value.location, Timestamp = time, Seq = seq ?? 0, }; unsynced[work.Key] = newitems[work.Key] = storage[work.Key] = w; // Do a delayed since if we finished a chapter, or started a new one if (old == null || work.Value.location == null || work.Value.location == 0 || work.Value.number > old.number || work.Value.seq > old.Seq) { do_delayed = true; WorkEvents.TryGetEvent(work.Key)?.OnChapterNumChanged(this, w); } else { WorkEvents.TryGetEvent(work.Key)?.OnLocationChanged(this, w); } } } if (newitems.Count > 0) { App.Database.SaveItems(newitems.Values.ToReadOnly()); if (serversync == SyncState.Ready || serversync == SyncState.Delayed) { if (do_delayed) { DelayedSyncAsync(10 * 1000); } else { DoSyncAsync(); } } } } })); }
public void DoSyncAsync(bool force = false) { Task.Factory.StartNew(() => { using (ReadWriteLock.UpgradeableReadLock()) { var settings = new JsonSerializerSettings() { MissingMemberHandling = MissingMemberHandling.Ignore }; Dictionary <long, Work> items; Dictionary <long, Work> current; long time; long old_sync; Task <HttpResponseMessage> responseTask; HttpResponseMessage response; Task <string> contentTask; string content; using (ReadWriteLock.WriteLock()) { if (serversync == SyncState.Disabled) { EndSyncEvent?.Invoke(this, new EventArgs <bool>(false)); //console.warn("dosync: FAILED. No credentials"); return; } // if we have waiting readers do it now if (ReadWriteLock.WaitingReadCount > 0) { force = true; } // Enforce 5 minutes gap between server sync. Don't want to hammer the server while scrolling through a fic var now = DateTime.UtcNow.Ticks / 10000; if (!force && now < no_sync_until) { //console.log("dosync: have to wait %i for timeout", no_sync_until - now); DelayedSyncAsync((int)(no_sync_until - now)); return; } serversync = SyncState.Syncing; // set to syncing! if (DelayedSyncCTS != null) { DelayedSyncCTS.Cancel(); DelayedSyncCTS = null; } no_sync_until = now + 5 * 60 * 1000; BeginSyncEvent?.Invoke(this, EventArgs.Empty); //console.log("dosync: sending GET request"); responseTask = HttpClient.GetAsync(new Uri(url_base, "Values?after=" + last_sync)); responseTask.TryWait(); response = responseTask.IsFaulted ? null : responseTask.Result; if (response == null || !response.IsSuccessStatusCode) { using (ReadWriteLock.WriteLock()) { //console.error("dosync: FAILED %s", response.ReasonPhrase); if (response != null && response.StatusCode == HttpStatusCode.Forbidden) { serversync = SyncState.Disabled; } else { serversync = SyncState.Ready; } EndSyncEvent?.Invoke(this, new EventArgs <bool>(false)); return; } } contentTask = response.Content.ReadAsStringAsync(); contentTask.Wait(); content = contentTask.Result; old_sync = last_sync; try { items = JsonConvert.DeserializeObject <Dictionary <long, Work> >(content, settings); } catch (Exception e) { App.Log(e); serversync = SyncState.Disabled; EndSyncEvent?.Invoke(this, new EventArgs <bool>(false)); return; } Dictionary <long, Work> newitems = new Dictionary <long, Work>(); foreach (var item in items) { item.Value.workid = item.Key; // Highest time value of incoming item is our new sync time if (item.Value.Timestamp > last_sync) { last_sync = item.Value.Timestamp; } Work old = null; if (!storage.ContainsKey(item.Key) || (old = storage[item.Key]).LessThanOrEqual(item.Value)) { // Remove from unsynced list (if it exists) if (unsynced.ContainsKey(item.Key)) { unsynced.Remove(item.Key); } // Grab the new details newitems[item.Key] = storage[item.Key] = item.Value; if (old == null || item.Value.location == null || item.Value.location == 0 || (old != null && item.Value.number > old.number)) { WorkEvents.TryGetEvent(item.Key)?.OnChapterNumChanged(this, item.Value); } else { WorkEvents.TryGetEvent(item.Key)?.OnLocationChanged(this, item.Value); } } // This kinda shouldn't happen, but apparently it did... we can deal with it though else { // Update the timestamp to newer than newest if (storage[item.Key].Timestamp <= item.Value.Timestamp) { storage[item.Key].Timestamp = item.Value.Timestamp + 1; } else { item.Value.Timestamp += 1; } // set as unsynced unsynced[item.Key] = storage[item.Key]; } } App.Database.SaveItems(newitems.Values.ToReadOnly()); current = unsynced; unsynced = new Dictionary <long, Work>(); time = last_sync; if (current.Count == 0) { App.Database.SaveVariable("last_sync", last_sync); serversync = SyncState.Ready; EndSyncEvent?.Invoke(this, new EventArgs <bool>(true)); return; } } foreach (var item in current.Values) { if (item.Timestamp > time) { time = item.Timestamp; } } var json = JsonConvert.SerializeObject(current); var postBody = new StringContent(json, System.Text.Encoding.UTF8, "application/json"); responseTask = HttpClient.PostAsync(new Uri(url_base, "Values"), postBody); responseTask.TryWait(); response = responseTask.IsFaulted ? null : responseTask.Result; if (response == null || !response.IsSuccessStatusCode) { using (ReadWriteLock.WriteLock()) { //console.error("dosync: FAILED %s", response.ReasonPhrase); if (response != null && response.StatusCode == HttpStatusCode.Forbidden) { last_sync = 0; serversync = SyncState.Disabled; } else { last_sync = old_sync; serversync = SyncState.Ready; unsynced = current; } App.Database.SaveVariable("last_sync", last_sync); EndSyncEvent?.Invoke(this, new EventArgs <bool>(false)); return; } } contentTask = response.Content.ReadAsStringAsync(); contentTask.Wait(); content = contentTask.Result; try { items = JsonConvert.DeserializeObject <Dictionary <long, Work> >(content, settings); } catch (Exception e) { App.Log(e); using (ReadWriteLock.WriteLock()) { serversync = SyncState.Disabled; App.Database.SaveVariable("last_sync", 0L); last_sync = 0; EndSyncEvent?.Invoke(this, new EventArgs <bool>(false)); return; } } //console.log("dosync: SUCCESS. %i conflicted items", Object.keys(items).length); using (ReadWriteLock.WriteLock()) { if (items.Count > 0) { App.Database.SaveVariable("last_sync", 0L); last_sync = 0; DoSyncAsync(true); return; } if (time > last_sync) { last_sync = time; App.Database.SaveVariable("last_sync", time); } if (unsynced.Count > 0) { DoSyncAsync(true); } else { serversync = SyncState.Ready; EndSyncEvent?.Invoke(this, new EventArgs <bool>(true)); } } } }, TaskCreationOptions.PreferFairness | TaskCreationOptions.LongRunning); }