Пример #1
0
 /// <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();
     }
 }
Пример #2
0
 /// <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();
                 }
             }
         }
     }
 }
Пример #3
0
        /// <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();
            }
        }
Пример #4
0
        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();
            }
        }
Пример #5
0
        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();
            }
        }
Пример #6
0
 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);
         }
     }
                     ));
 }
Пример #7
0
        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);
                            }
                        }
                    });
                }
            }));
        }
Пример #8
0
        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;
                }
            }));
        }
Пример #9
0
        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();
                            }
                        }
                    }
                }
            }));
        }
Пример #10
0
        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);
        }