protected bool TryApply(MutationPacket mutationPacket, out Mutation mutation, out MutationResult result) { FragmentKey key = fragmentKeyFactory.FromBytes(mutationPacket.GetKey()); mutation = mutationFactory.FromBytes(mutationPacket.GetPayload()); result = mutation.Mutate(state, key, mutationPacket.GetRequester()); if (result.IsFailure()) { return(false); } if (result.IsSuccess()) { bool isUpdate = state.ContainsKey(key); state = state.CloneWith(key, result.GetFragment()); if (isUpdate) { SafeInvoker.Invoke(log, OnFragmentUpdatedCallback, result.GetFragment(), state, key, mutation); } else { SafeInvoker.Invoke(log, OnFragmentInsertedCallback, result.GetFragment(), state, key, mutation); } } else if (result.IsDelete()) { if (state.ContainsKey(key)) { state = state.CloneWithout(key); SafeInvoker.Invoke(log, OnFragmentDeletedCallback, state, key, mutation); } } SafeInvoker.Invoke(log, OnStateChangedCallback, state, key, mutation); return(true); }
private static bool GetMessageCollection(IChat chat, out IEnumerator enumerator) { enumerator = null; IChatMessageCollection messageCollection; if (!SafeInvoker.Invoke(() => chat.Messages, out messageCollection)) { return(false); } ChatMessageEnumerator messageEnumerator; if (!SafeInvoker.Invoke( () => ChatMessageEnumerator.Create(messageCollection), out messageEnumerator)) { return(false); } Logger.Info( "{0} message(s) found in this chat.", messageEnumerator.Count); enumerator = messageEnumerator; return(true); }
private void OnPacketReceived(Packet packet) { if (packet is FragmentPacket fragmentPacket) { FragmentKey key = fragmentKeyFactory.FromBytes(fragmentPacket.GetKey()); state = state.CloneWith(key, fragmentFactory.FromBytes(fragmentPacket.GetPayload())); } else if (packet is MutationPacket mutationPacket) { // If mutation was requested by me, then this request is no longer pending if (mutationPacket.GetRequester().Equals(client.id)) { pending.Remove(mutationPacket.GetId()); } if (!TryApply(mutationPacket, out Mutation mutation, out MutationResult result)) { // This should never happen since the mutation has already been succesfully applied at the Oracle. This // indicates that replication state is corrupt. This is a good reason to directly disconnect from the server. string message = "Fatal Karmax replication failure"; log.Error($"{message}. Corrupt state detected while applying {mutation.GetType().Name} on fragment[{fragmentKeyFactory.FromBytes(mutationPacket.GetKey()).AsString()}]. Reason: {result.GetFailureReason()}"); client.Leave(message); return; } } else if (packet is MutationFailedPacket mutationFailedPacket) { var mutationId = mutationFailedPacket.GetId(); log.Warning($"Mutation[{mutationId}] failed. Reason: {mutationFailedPacket.GetFailureReason()}. Details: {pending[mutationId]}"); pending.Remove(mutationId); SafeInvoker.Invoke(log, OnMutationFailedCallback, mutationId, mutationFailedPacket.GetFailureReason()); } }
public static ISafeInvoker <T> CreateSafeInvoker <T>(Func <T> getValue) where T : class { var lifeTime = new LifetimeScope(new ComponentRegistry()); var safeInvoker = new SafeInvoker <T>(() => new Owned <T>(getValue(), lifeTime)); return(safeInvoker); }
public static ISafeInvoker <T> CreateSafeInvoker <T>(T value) where T : class { var lifeTime = new LifetimeScope(new ComponentRegistry()); var owned = new Owned <T>(value, lifeTime); var safeInvoker = new SafeInvoker <T>(() => owned); return(safeInvoker); }
private void HandleMutationBy(MutationPacket mutationPacket, Guid requester) { if (!TryApply(mutationPacket, out Mutation mutation, out MutationResult result)) { if (requester.Equals(Guid.Empty)) { log.Warning($"Mutation[{mutationPacket.GetId()}] failed. Reason: {result.GetFailureReason()}. Details: {mutation.GetType().Name} on fragment[{fragmentKeyFactory.FromBytes(mutationPacket.GetKey()).AsString()}].\nStackTrace: {Environment.StackTrace}"); SafeInvoker.Invoke(log, OnMutationFailedCallback, mutationPacket.GetId(), result.GetFailureReason()); } else { server.Send(requester, new MutationFailedPacket(mutationPacket.GetId(), result.GetFailureReason())); } return; } server.Broadcast(mutationPacket); }
public override bool StoreMessage(string path, IChat chat, IChatMessage message) { object[] properties; if (!SafeInvoker.Invoke(() => ExtractProperties(message), out properties)) { Logger.Error("Cannot retrieve the message properties."); return(false); } if (properties == null) { // The message is correctly processed, but should be skipped. return(true); } StreamWriter writer = storage.GetWriter(path + Extension); writer.WriteLine(Format, properties); return(true); }
private JsonTextWriter CreateWriter(string path, IChat chat) { JsonTextWriter writer = new JsonTextWriter( storage.GetWriter(path + ".json")) { Formatting = Formatting.Indented, Indentation = 4, IndentChar = ' ' }; writer.WriteStartObject(); Action action = delegate { writer.WritePropertyName("Chat"); writer.WriteStartObject(); writer.WriteProperty("Description", chat.Description); writer.WriteProperty("FriendlyName", chat.FriendlyName); writer.WriteProperty("MyRole", chat.MyRole); writer.WriteProperty("MyStatus", chat.MyStatus); writer.WriteProperty("Name", chat.Name); writer.WriteProperty("Topic", chat.Topic); writer.WriteProperty("Type", chat.Type); writer.WritePropertyName("Members"); writer.WriteStartArray(); foreach (IUser user in chat.Members) { writer.WriteValue(user.Handle); } writer.WriteEndArray(); writer.WriteEndObject(); }; if (!SafeInvoker.Invoke(action)) { Logger.Error("Couldn't store chat properties."); return(null); } writer.WriteProperty("ExportStartTime", DateTime.Now); writer.WriteProperty("SkypeHistorianVersion", App.Version); writer.WritePropertyName("Messages"); writer.WriteStartArray(); return(writer); }
private XmlTextWriter CreateWriter(string path, IChat chat) { XmlTextWriter writer = new XmlTextWriter( storage.GetWriter(path + ".xml")) { Formatting = Formatting.Indented, Indentation = 4, IndentChar = ' ' }; writer.WriteStartDocument(); writer.WriteStartElement("Chat"); writer.WriteAttribute("ExportStartTime", DateTime.Now); writer.WriteAttribute("SkypeHistorianVersion", App.Version); Action action = delegate { writer.WriteAttribute("Description", chat.Description); writer.WriteAttribute("FriendlyName", chat.FriendlyName); writer.WriteAttribute("MyRole", chat.MyRole); writer.WriteAttribute("MyStatus", chat.MyStatus); writer.WriteAttribute("Name", chat.Name); writer.WriteAttribute("Topic", chat.Topic); writer.WriteAttribute("Type", chat.Type); writer.WriteStartElement("Members"); foreach (IUser user in chat.Members) { writer.WriteStartElement("Member"); writer.WriteAttribute("Handle", user.Handle); writer.WriteAttribute("FullName", user.FullName); writer.WriteEndElement(); } writer.WriteEndElement(); }; if (!SafeInvoker.Invoke(action)) { Logger.Error("Couldn't store chat properties."); return(null); } writer.WriteStartElement("Messages"); return(writer); }
private void Cleanup() { DebugLogger.Log("Cleaning up..."); if (Directory.Exists(DownloadDirectoryPath)) { SafeInvoker.Invoke(() => DirectoryOperations.Delete(DownloadDirectoryPath, true), null, _ => { DebugLogger.LogWarning("Unable to cleanup torrent download directory."); }); } if (File.Exists(TorrentFilePath)) { SafeInvoker.Invoke(() => FileOperations.Delete(TorrentFilePath), null, _ => { DebugLogger.LogWarning("Unable to cleanup torrent file."); }); } DebugLogger.Log("Cleanup completed."); }
private void StartSkype() { Skype4COMWrapper.Skype skype; if (!SafeInvoker.Invoke(() => new Skype4COMWrapper.Skype(), out skype)) { Context.StatusCode = StatusCode.SkypeInitializationFailed; return; } Context.Skype = skype; Action action = delegate { if (!skype.Client.IsRunning) { skype.Client.Start(true, true); } }; if (!SafeInvoker.Invoke(action)) { Context.StatusCode = StatusCode.SkypeStartFailed; return; } }
private bool GetChatCollection(out IEnumerator enumerator) { enumerator = null; IChatCollection chatCollection; Dispatcher.Invoke(new Action( () => bottomInfoLabel.Content = waitingForSkypeString)); Thread.Sleep(100); // I don't understand why, but it helps to "unhang" showing this page. Logger.Info("Awaiting for Skype response ..."); if (!SafeInvoker.Repeat(() => Context.Skype.Chats, out chatCollection, 3)) { return(false); } int chatCount; if (!SafeInvoker.Invoke(() => chatCollection.Count, out chatCount)) { return(false); } Context.ChatCount = chatCount; int messagesCount; // ReSharper disable UseIndexedProperty // Because indexed property fail an installer building. if (!SafeInvoker.Invoke(() => Context.Skype.get_Messages(String.Empty).Count, // ReSharper restore UseIndexedProperty out messagesCount)) { return(false); } Context.MessagesCount = messagesCount; Logger.Info("{0} chat(s) and {1} messages found.", chatCount, messagesCount); return(SafeInvoker.Invoke(chatCollection.GetEnumerator, out enumerator)); }
public override bool StoreMessage(string path, IChat chat, IChatMessage message) { JsonTextWriter writer; if (!writers.TryGetValue(path, out writer)) { writer = CreateWriter(path, chat); if (writer == null) { return(false); } writers[path] = writer; } Action retrieveMessageProperties = delegate { writer.WriteStartObject(); writer.WriteProperty("Id", message.Id); writer.WriteProperty("Body", message.Body); writer.WriteProperty("TimeStamp", message.Timestamp); writer.WriteProperty("FromDisplayName", message.FromDisplayName); writer.WriteProperty("EditedBy", message.EditedBy); writer.WriteProperty("EditedTimeStamp", message.EditedTimestamp); writer.WriteProperty("FromHandle", message.FromHandle); writer.WriteProperty("LeaveReason", message.LeaveReason); writer.WriteProperty("Type", message.Type); writer.WriteProperty("Status", message.Status); writer.WriteEndObject(); }; if (!SafeInvoker.Invoke(retrieveMessageProperties)) { Logger.Error("Cannot retrieve message properties."); return(false); } return(true); }
private void ExportChats() { Context.IsExportingInProgress = true; Logger.Info("About to get chats collection ..."); IEnumerator chatEnumerator; if (!GetChatCollection(out chatEnumerator)) { Context.StatusCode = StatusCode.SkypeCannotGetChatCollection; } else if (Context.ChatCount > 0) { Context.ProgressStartedAt = DateTime.Now; Dispatcher.Invoke(new Action( () => bottomInfoLabel.Content = String.Format( messagesProcessedString, 0, "-", "--"))); Dispatcher.Invoke(new Action( () => progressBar.Maximum = Context.MessagesCount)); while (true) { IChat chat; if (!SafeInvoker.Invoke(() => chatEnumerator.MoveNext() ? (IChat)chatEnumerator.Current : null, out chat)) { Context.StatusCode = StatusCode.SkypeCannotGetChat; break; } if (chat == null) { Logger.Info("Chat collection processing is finished."); break; } if (ExportChat(chat)) { Context.ExportedChatCount += 1; Dispatcher.Invoke(new Action( () => topInfoLabel.Content = String.Format( chatsExportedString, Context.ExportedChatCount, Context.ChatCount))); } else if ( Context.StatusCode == StatusCode.NoError || Context.StatusCode == StatusCode.SkypeCannotGetChatCollection) { Logger.Warn( "The chat is skipped due to the error: {0}", Context.StatusCode); // Reset the error as we've just skipped this error. Context.StatusCode = StatusCode.NoError; } Logger.Info("Date filter skipped count: {0}", Context.DateFilterSkippedCount); } } Dispatcher.Invoke(new Action( () => topInfoLabel.Content = String.Empty)); Dispatcher.Invoke(new Action( () => bottomInfoLabel.Content = String.Empty)); Context.OutputWriter.Storage.CloseProgressChanged += StorageCloseProgressChanged; Context.OutputWriter.Close(); Logger.Info("{0} messages of {1} are exported.", Context.ProcessedMessagesCount, Context.MessagesCount); Logger.Info("{0} chats of {1} are exported.", Context.ExportedChatCount, Context.ChatCount); if (Context.StatusCode == StatusCode.NoError) { Context.StatusCode = StatusCode.Finished; } Context.IsExportingInProgress = false; }
private bool ExportChat(IChat chat) { Logger.Info("Started processing a chat: {0}.", chat.Name); IEnumerator messageEnumerator; if (!GetMessageCollection(chat, out messageEnumerator)) { Context.StatusCode = StatusCode.CannotGetMessageCollection; return(false); } string members; if (!SafeInvoker.Invoke(() => GetMembersString(chat), out members)) { Context.StatusCode = StatusCode.SkypeCannotGetChatProperties; return(false); } // Debug counters. int exportedMessageCount = 0; int skippedMessageCount = 0; Logger.Info("Started processing {0} chat.", members); while (true) { IChatMessage message; if (!SafeInvoker.Invoke(() => messageEnumerator.MoveNext() ? (IChatMessage)messageEnumerator.Current : null, out message)) { Context.StatusCode = StatusCode.SkypeCannotGetMessage; break; } if (message == null) { Logger.Info("Messages processing is finished."); break; } DateTime messageTimeStamp; if (!SafeInvoker.Invoke(() => message.Timestamp, out messageTimeStamp)) { Context.StatusCode = StatusCode.SkypeCannotGetMessageTimeStamp; break; } if (!Context.UseDateFilter || (Context.DateFilterStartDate <= messageTimeStamp && Context.DateFilterEndDate > messageTimeStamp)) { string chatPath = Context.GroupingStrategy.GetChatPathForMessage( members, messageTimeStamp); bool successfullyStored = false; try { successfullyStored = Context.OutputWriter.StoreMessage( chatPath, chat, message); } catch (Exception ex) { Logger.ErrorException("Message storing has failed.", ex); Context.StatusCode = StatusCode.MessageStoringFailed; break; } if (!successfullyStored) { Context.StatusCode = StatusCode.MessageStoringFailed; break; } else { exportedMessageCount += 1; } } else { Context.DateFilterSkippedCount += 1; skippedMessageCount += 1; } Context.ProcessedMessagesCount += 1; } Logger.Info( "Exported {0} message(s), skipped by the filter {1} message(s).", exportedMessageCount, skippedMessageCount); return(true); }
public PlayerAnimator(PlayerDrawable playerDrawable) { _playerDrawable = playerDrawable; _frameCallbackInvoker = new SafeInvoker <Float2D>(FrameCallback); _endCallback = new SafeInvoker(EndCallback); }