Ejemplo n.º 1
0
 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());
     }
 }
Ejemplo n.º 2
0
        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);
        }
Ejemplo n.º 3
0
        public Guid Request(FragmentKey key, Mutation mutation)
        {
            if (!isAttached)
            {
                throw log.ExitError(new Exception("Cannot Request the mutation of a fragment if the Karmax container is no longer attached to the Server."));
            }
            Guid mutationId = Guid.NewGuid();

            byte[]         keyBytes       = fragmentKeyFactory.GetBytes(key);
            byte[]         payload        = mutationFactory.GetBytes(mutation);
            MutationPacket mutationPacket = new MutationPacket(mutationId, containerId, keyBytes, payload);

            Request(mutationPacket, mutation);
            return(mutationId);
        }
Ejemplo n.º 4
0
        internal override sealed MutationResult Mutate(IReadOnlyDictionary <FragmentKey, Fragment> state, FragmentKey key, Guid requester)
        {
            MutationResult result;

            if (state.TryGetValue(key, out Fragment fragment))
            {
                if (!(fragment is T fragmentT))
                {
                    log.Warning($"Can not {GetType().Name} a {typeof(T).Name} at fragment[{key.AsString()}], because that fragment is of type {fragment.GetType().Name}.");
                    return(MutationResult.FragmentTypeMismatchFailure);
                }
                result = Update(fragmentT, state, key, requester);
                if (result == null)
                {
                    log.Warning($"{GetType().Name}.Update returned null, which is not allowed.");
                    return(MutationResult.ResultNullFailure);
                }
            }
            else
            {
                result = Insert(state, key, requester);
                if (result == null)
                {
                    log.Warning($"{GetType().Name}.Insert returned null, which is not allowed.");
                    return(MutationResult.ResultNullFailure);
                }
            }
            return(result);
        }
Ejemplo n.º 5
0
 protected abstract UpdateResult <T> Update(T fragment, IReadOnlyDictionary <FragmentKey, Fragment> state, FragmentKey key, Guid requester);
Ejemplo n.º 6
0
 protected abstract InsertResult <T> Insert(IReadOnlyDictionary <FragmentKey, Fragment> state, FragmentKey key, Guid requester);
Ejemplo n.º 7
0
 protected override UpdateResult<Counter> Update(Counter fragment, IReadOnlyDictionary<FragmentKey, Fragment> state, FragmentKey key, Guid requester)
 {
     return UpdateResult<Counter>.Success(new Counter(fragment.GetValue() * product));
 }
Ejemplo n.º 8
0
 protected abstract DeleteResult Delete(T fragment, IReadOnlyDictionary <FragmentKey, Fragment> state, FragmentKey fragmentId, Guid requester);
Ejemplo n.º 9
0
 protected override DeleteResult Delete(Counter counter, IReadOnlyDictionary <FragmentKey, Fragment> state, FragmentKey key, Guid requester)
 {
     return(DeleteResult.Delete());
 }
Ejemplo n.º 10
0
 private void OnStateChanged(IReadOnlyDictionary <FragmentKey, Fragment> state, FragmentKey key, Mutation mutation)
 {
     lastStateText = string.Join("\n", state.Select(kvp => $"<b>{kvp.Key.AsString()}</b>: {kvp.Value}").Reverse());
     UpdateText();
 }
Ejemplo n.º 11
0
        internal override MutationResult Mutate(IReadOnlyDictionary <FragmentKey, Fragment> state, FragmentKey key, Guid requester)
        {
            if (state.ContainsKey(key))
            {
                log.Warning($"Can not {GetType().Name} a {typeof(T).Name} at fragment[{key.AsString()}], because that fragment already exists.");
                return(MutationResult.FragmentAlreadyExistsFailure);
            }
            InsertResult <T> result = Insert(state, key, requester);

            if (result == null)
            {
                log.Warning($"{GetType()}.Insert returned null, while this is not allowed.");
                return(MutationResult.ResultNullFailure);
            }
            return(result);
        }
Ejemplo n.º 12
0
 protected override InsertResult <Counter> Insert(IReadOnlyDictionary <FragmentKey, Fragment> state, FragmentKey key, Guid requester)
 {
     return(InsertResult <Counter> .Success(new Counter(amount)));
 }
Ejemplo n.º 13
0
 internal abstract MutationResult Mutate(IReadOnlyDictionary <FragmentKey, Fragment> state, FragmentKey key, Guid requester);