public List <Task> CreateRelationshipEdges(bool forward) { TimeSpan intervalStart = runtimeStopwatch.Elapsed; promises = loader.ProcessEdges((fromUserId, toUserId) => { // Segment updates into disjoint update groups, based on source / target node id bool skip = forward ? fromUserId > toUserId : fromUserId < toUserId; if (skip) { return(null); // skip this edge for this time round } IChirperAccount fromUser = this.Users[fromUserId]; return(AddChirperFollower(fromUser, fromUserId, toUserId)); }, i => { // Show progress interval breakdown TimeSpan currentRuntime = runtimeStopwatch.Elapsed; LogMessage("Links created: {0,10} Time: {1} Cumulative: {2}", i, currentRuntime - intervalStart, currentRuntime); intervalStart = runtimeStopwatch.Elapsed; // Don't include log writing in the interval. }, pipeline); return(promises); }
public async Task <bool> Run() { if (UserId == 0) { throw new ArgumentNullException("UserId", "No user UserId provided"); } Console.WriteLine("ChirperClient UserId={0}", UserId); bool ok = true; try { var config = ClientConfiguration.LocalhostSilo(); GrainClient.Initialize(config); IChirperAccount account = GrainClient.GrainFactory.GetGrain <IChirperAccount>(UserId); publisher = account; List <ChirperMessage> chirps = await account.GetReceivedMessages(10); // Process the most recent chirps received foreach (ChirperMessage c in chirps) { this.NewChirpArrived(c); } if (Snapshot) { Console.WriteLine("--- Press any key to exit ---"); Console.ReadKey(); } else { // ... and then subscribe to receive any new chirps viewer = await GrainClient.GrainFactory.CreateObjectReference <IChirperViewer>(this); if (!this.IsPublisher) { Console.WriteLine("Listening for new chirps..."); } await account.ViewerConnect(viewer); // Sleeps forwever, so Ctrl-C to exit Thread.Sleep(-1); } } catch (Exception exc) { Console.WriteLine("Error connecting Chirper client for user={0}. Exception:{1}", UserId, exc); ok = false; } return(ok); }
private void ForEachUser(Action <IChirperAccount> action) { List <Task> promises = new List <Task>(); foreach (long userId in loader.Users.Keys) { IChirperAccount user = loader.Users[userId]; Task p = Task.Factory.StartNew(() => action(user)); pipeline.Add(p); promises.Add(p); } pipeline.Wait(); Task.WhenAll(promises).Wait(); }
private async Task AddChirperFollower(IChirperAccount fromUser, long fromUserId, long toUserId) { // Create subscriptions between two Chirper users try { await fromUser.FollowUserId(toUserId); Interlocked.Increment(ref numRelationships); } catch (Exception exc) { ReportError(string.Format("Error adding follower relationship from user id {0} to user id {1}", fromUserId, toUserId), exc); throw exc.GetBaseException(); } }
public async Task<bool> Run() { if (UserId == 0) throw new ArgumentNullException("UserId", "No user UserId provided"); Console.WriteLine("ChirperClient UserId={0}", UserId); bool ok = true; try { var config = ClientConfiguration.LocalhostSilo(); GrainClient.Initialize(config); IChirperAccount account = GrainClient.GrainFactory.GetGrain<IChirperAccount>(UserId); publisher = account; List<ChirperMessage> chirps = await account.GetReceivedMessages(10); // Process the most recent chirps received foreach (ChirperMessage c in chirps) { this.NewChirpArrived(c); } if (Snapshot) { Console.WriteLine("--- Press any key to exit ---"); Console.ReadKey(); } else { // ... and then subscribe to receive any new chirps viewer = await GrainClient.GrainFactory.CreateObjectReference<IChirperViewer>(this); if (!this.IsPublisher) Console.WriteLine("Listening for new chirps..."); await account.ViewerConnect(viewer); // Sleeps forwever, so Ctrl-C to exit Thread.Sleep(-1); } } catch (Exception exc) { Console.WriteLine("Error connecting Chirper client for user={0}. Exception:{1}", UserId, exc); ok = false; } return ok; }
private async Task AddChirperUser(ChirperUserInfo userData) { // Create Chirper account grain for this user long userId = userData.UserId; string userAlias = userData.UserAlias; IChirperAccount grain = GrainClient.GrainFactory.GetGrain <IChirperAccount>(userId); this.Users[userId] = grain; try { // Force creation of the grain by sending it a first message to set user alias ChirperUserInfo userInfo = ChirperUserInfo.GetUserInfo(userId, userAlias); await grain.SetUserDetails(userInfo); Interlocked.Increment(ref numUsers); } catch (Exception exc) { ReportError("Error creating user id " + userId, exc); throw exc.GetBaseException(); } }
public SimulatedUser(IChirperAccount user) { this.user = user; this.getUserIdAsync = user.GetUserId(); }
public async Task RunAsync(IClusterClient client) { this.ShowHelp(true); while (true) { var command = Console.ReadLine(); if (command == "/help") { this.ShowHelp(); } else if (command == "/quit") { return; } else if (command.StartsWith("/user ")) { var match = Regex.Match(command, @"/user (?<username>\w{1,100})"); if (match.Success) { await this.Unobserve(); var username = match.Groups["username"].Value; this.account = client.GetGrain <IChirperAccount>(username); Console.WriteLine($"The current user is now [{username}]"); } else { Console.WriteLine("Invalid username. Try again or type /help for a list of commands."); } } else if (command.StartsWith("/follow ")) { if (this.EnsureActiveAccount()) { var match = Regex.Match(command, @"/follow (?<username>\w{1,100})"); if (match.Success) { var targetName = match.Groups["username"].Value; await this.account.FollowUserIdAsync(targetName); Console.WriteLine($"[{this.account.GetPrimaryKeyString()}] is now following [{targetName}]"); } else { Console.WriteLine("Invalid target username. Try again or type /help for a list of commands."); } } } else if (command == "/following") { if (this.EnsureActiveAccount()) { (await this.account.GetFollowingListAsync()) .ForEach(_ => Console.WriteLine(_)); } } else if (command == "/followers") { if (this.EnsureActiveAccount()) { (await this.account.GetFollowersListAsync()) .ForEach(_ => Console.WriteLine(_)); } } else if (command == "/observe") { if (this.EnsureActiveAccount()) { if (this.viewer == null) { this.viewer = await client.CreateObjectReference <IChirperViewer>(new ChirperConsoleViewer(this.account.GetPrimaryKeyString())); } await this.account.SubscribeAsync(this.viewer); Console.WriteLine($"Now observing [{this.account.GetPrimaryKeyString()}]"); } } else if (command == "/unobserve") { if (this.EnsureActiveAccount()) { await this.Unobserve(); } } else if (command.StartsWith("/unfollow ")) { if (this.EnsureActiveAccount()) { var match = Regex.Match(command, @"/unfollow (?<username>\w{1,100})"); if (match.Success) { var targetName = match.Groups["username"].Value; await this.account.UnfollowUserIdAsync(targetName); Console.WriteLine($"[{this.account.GetPrimaryKeyString()}] is no longer following [{targetName}]"); } else { Console.WriteLine("Invalid target username. Try again or type /help for a list of commands."); } } } else if (command.StartsWith("/chirp ")) { if (this.EnsureActiveAccount()) { var match = Regex.Match(command, @"/chirp (?<message>.+)"); if (match.Success) { var message = match.Groups["message"].Value; await this.account.PublishMessageAsync(message); Console.WriteLine("Published the new message!"); } else { Console.WriteLine("Invalid chirp. Try again or type /help for a list of commands."); } } } else { Console.WriteLine("Unknown command. Type /help for list of commands."); } } }