Example #1
0
        public async Task Write(GStoreObjectIdentifier gStoreObjectIdentifier, string newValue)
        {
            try
            {
                if (!connectionManager.IsMasterForPartition(gStoreObjectIdentifier.PartitionId))
                {
                    throw new Exception("Not master");
                }

                // Acquire lock on local object
                ReaderWriterLockEnhancedSlim objectLock = GetObjectLock(gStoreObjectIdentifier);
                int lockId = objectLock.EnterWriteLock();

                // Send lock requests to all remote objects
                IDictionary <string, int> replicaLocks = await LockController.ExecuteAsync(connectionManager, gStoreObjectIdentifier);

                // Once lock confirmations arrive, write to local object and unlock it
                GStoreObject gStoreObject = AddOrUpdate(gStoreObjectIdentifier, newValue);
                objectLock.ExitWriteLock(lockId);

                // Send write requests to all remote objects
                await WriteReplicaController.ExecuteAsync(connectionManager, gStoreObject, replicaLocks);
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
            }
        }
        public static async Task ExecuteAsync(ConnectionManager connectionManager, GStoreObject gStoreObject, int version)
        {
            GStoreObjectIdentifier gStoreObjectIdentifier = gStoreObject.Identifier;

            // Get all replicas associated to this Partition
            IImmutableSet <Server> servers = connectionManager.GetAliveServers(gStoreObjectIdentifier.PartitionId);

            IDictionary <string, Task> writeTasks = new Dictionary <string, Task>();

            foreach (Server server in servers)
            {
                if (server.Id != connectionManager.SelfServerId)
                {
                    writeTasks.Add(server.Id, ExecuteServerAsync(connectionManager, server.Stub, gStoreObject, version));
                }
            }

            foreach (KeyValuePair <string, Task> writeTaskPair in writeTasks)
            {
                string serverId = writeTaskPair.Key;
                try
                {
                    await writeTaskPair.Value;
                }
                catch (Grpc.Core.RpcException e) when(e.StatusCode == Grpc.Core.StatusCode.Internal)
                {
                    connectionManager.DeclareDead(serverId);
                }
            }
        }
        private static GStoreObjectReplica CreateObjectReplica(DataObjectReplica dataObjectReplica)
        {
            GStoreObjectIdentifier gStoreObjectIdentifier = new GStoreObjectIdentifier(dataObjectReplica.Object.ObjectIdentifier.PartitionId, dataObjectReplica.Object.ObjectIdentifier.ObjectId);
            GStoreObject           gStoreObject           = new GStoreObject(gStoreObjectIdentifier, dataObjectReplica.Object.Value);

            return(new GStoreObjectReplica(gStoreObject, dataObjectReplica.IsMasterReplica));
        }
Example #4
0
        private Empty ExecuteWrite(WriteRequest request)
        {
            Console.WriteLine($"Write Replica request -> PartitionId: {request.Object.ObjectIdentifier.PartitionId} ObjectId: {request.Object.ObjectIdentifier.ObjectId} Value: {request.Object.Value} LockId: {request.LockId}");
            GStoreObjectIdentifier gStoreObjectIdentifier = new GStoreObjectIdentifier(request.Object.ObjectIdentifier.PartitionId, request.Object.ObjectIdentifier.ObjectId);

            gStore.WriteReplica(gStoreObjectIdentifier, request.Object.Value, request.LockId);
            return(new Empty());
        }
Example #5
0
 private GStoreObjectVersioning GetObjectVersioning(GStoreObjectIdentifier gStoreObjectIdentifier)
 {
     return(ObjectVersionings.GetOrAdd(gStoreObjectIdentifier,
                                       (key) =>
     {
         return new GStoreObjectVersioning();
     }));
 }
Example #6
0
 private ReaderWriterLockEnhancedSlim GetObjectLock(GStoreObjectIdentifier gStoreObjectIdentifier)
 {
     return(ObjectLocks.GetOrAdd(gStoreObjectIdentifier,
                                 (key) =>
     {
         return new ReaderWriterLockEnhancedSlim();
     }));
 }
Example #7
0
        private async Task <Empty> ExecuteWrite(GStoreWriteRequest request)
        {
            Console.WriteLine($"Write request -> PartitionId: {request.Object.ObjectIdentifier.PartitionId} ObjectId: {request.Object.ObjectIdentifier} Value: {request.Object.Value}");

            GStoreObjectIdentifier gStoreObjectIdentifier = new GStoreObjectIdentifier(request.Object.ObjectIdentifier.PartitionId, request.Object.ObjectIdentifier.ObjectId);
            await gStore.Write(gStoreObjectIdentifier, request.Object.Value);

            return(new Empty());
        }
Example #8
0
        public int Lock(GStoreObjectIdentifier gStoreObjectIdentifier)
        {
            ReaderWriterLockEnhancedSlim objectLock = GetObjectLock(gStoreObjectIdentifier);
            string masterId = connectionManager.GetPartitionMasterId(gStoreObjectIdentifier.PartitionId);
            int    lockId   = objectLock.EnterWriteLock();
            ConcurrentDictionary <int, GStoreObjectIdentifier> locks = MastersLocks.GetOrAdd(masterId, (masterId) => new ConcurrentDictionary <int, GStoreObjectIdentifier>());

            locks.TryAdd(lockId, gStoreObjectIdentifier);
            return(lockId);
        }
Example #9
0
        public int GetObjectVersionNumber(GStoreObjectIdentifier gStoreObjectIdentifier)
        {
            int version = ObjectVersionNumber.GetOrAdd(gStoreObjectIdentifier,
                                                       (key) =>
            {
                return(0);
            });

            return(version);
        }
Example #10
0
        private LockReply ExecuteLock(LockRequest request)
        {
            Console.WriteLine($"Lock request -> PartitionId: {request.ObjectIdentifier.PartitionId} ObjectId: {request.ObjectIdentifier.ObjectId}");
            GStoreObjectIdentifier gStoreObjectIdentifier = new GStoreObjectIdentifier(request.ObjectIdentifier.PartitionId, request.ObjectIdentifier.ObjectId);
            int lockId = gStore.Lock(gStoreObjectIdentifier);

            return(new LockReply
            {
                LockId = lockId
            });
        }
Example #11
0
 private void AddOrUpdateObjectVersionServerWriter(GStoreObjectIdentifier gStoreObjectIdentifier, string serverId)
 {
     _ = ObjectVersionServerWriter.AddOrUpdate(gStoreObjectIdentifier,
                                               (key) =>
     {
         return(serverId);
     },
                                               (key, value) =>
     {
         return(serverId);
     });
 }
Example #12
0
 private void SetObjectVersionNumber(GStoreObjectIdentifier gStoreObjectIdentifier, int version)
 {
     _ = ObjectVersionNumber.AddOrUpdate(gStoreObjectIdentifier,
                                         (key) =>
     {
         return(version);
     },
                                         (key, value) =>
     {
         return(version);
     }
                                         );
 }
Example #13
0
 private GStoreObject AddOrUpdate(GStoreObjectIdentifier gStoreObjectIdentifier, string newValue)
 {
     return(DataStore.AddOrUpdate(gStoreObjectIdentifier,
                                  (id) =>
     {
         return new GStoreObject(id, newValue);
     },
                                  (id, gStoreObject) =>
     {
         gStoreObject.Value = newValue;
         return gStoreObject;
     }));
 }
Example #14
0
        public string Read(GStoreObjectIdentifier gStoreObjectIdentifier)
        {
            ReaderWriterLockEnhancedSlim objectLock = GetObjectLock(gStoreObjectIdentifier);
            string value = null;
            int    id    = objectLock.EnterReadLock();

            if (DataStore.TryGetValue(gStoreObjectIdentifier, out GStoreObject gStoreObject))
            {
                value = gStoreObject.Value;
            }
            objectLock.ExitReadLock(id);
            return(value);
        }
        private GStoreReadReply ExecuteRead(GStoreReadRequest request)
        {
            Console.WriteLine($"Read request -> PartitionId: {request.ObjectIdentifier.PartitionId} ObjectId: {request.ObjectIdentifier.ObjectId}");
            GStoreObjectIdentifier gStoreObjectIdentifier = new GStoreObjectIdentifier(request.ObjectIdentifier.PartitionId, request.ObjectIdentifier.ObjectId);
            string value = gStore.Read(gStoreObjectIdentifier);

            if (value == null)
            {
                value = "N/A";
            }
            return(new GStoreReadReply
            {
                Object = DataObjectBuilder.FromObjectIdentifier(request.ObjectIdentifier, value)
            });
        }
Example #16
0
        private int GetAndIncrementObjectVersionNumber(GStoreObjectIdentifier gStoreObjectIdentifier)
        {
            int version = ObjectVersionNumber.AddOrUpdate(gStoreObjectIdentifier,
                                                          (key) =>
            {
                return(1);
            },
                                                          (key, value) =>
            {
                return(++value);
            }
                                                          );

            return(version);
        }
Example #17
0
        public void WriteReplica(GStoreObjectIdentifier gStoreObjectIdentifier, string newValue, int lockId)
        {
            ReaderWriterLockEnhancedSlim objectLock = GetObjectLock(gStoreObjectIdentifier);

            if (!objectLock.IsWriteLockValid(lockId))
            {
                // throw error
            }

            AddOrUpdate(gStoreObjectIdentifier, newValue);

            objectLock.ExitWriteLock(lockId);

            string masterId = connectionManager.GetPartitionMasterId(gStoreObjectIdentifier.PartitionId);

            MastersLocks.TryGetValue(masterId, out ConcurrentDictionary <int, GStoreObjectIdentifier> locks);
            locks.TryRemove(lockId, out _);
        }
Example #18
0
        public async Task CleanLocks(string masterId)
        {
            MastersLocks.TryGetValue(masterId, out ConcurrentDictionary <int, GStoreObjectIdentifier> masterLocks);

            if (masterLocks == null)
            {
                return;
            }

            IDictionary <int, Task <string> > tasks = new Dictionary <int, Task <string> >();

            foreach (KeyValuePair <int, GStoreObjectIdentifier> locks in masterLocks)
            {
                int lockId = locks.Key;
                GStoreObjectIdentifier gStoreObjectIdentifier = locks.Value;

                ReaderWriterLockEnhancedSlim objectLock = GetObjectLock(gStoreObjectIdentifier);
                if (!objectLock.IsWriteLockValid(lockId))
                {
                    throw new Exception("Invalid lock");
                }

                Task <string> task = ReadRecoveryController.ExecuteAsync(connectionManager, gStoreObjectIdentifier);
                tasks.Add(lockId, task);
            }

            foreach (KeyValuePair <int, Task <string> > taskPair in tasks)
            {
                Task <string> task   = taskPair.Value;
                int           lockId = taskPair.Key;

                masterLocks.TryGetValue(lockId, out GStoreObjectIdentifier gStoreObjectIdentifier);
                ReaderWriterLockEnhancedSlim objectLock = GetObjectLock(gStoreObjectIdentifier);

                string value = await task;
                if (value != null)
                {
                    _ = AddOrUpdate(gStoreObjectIdentifier, value);
                }

                Console.WriteLine("Cleaned one lock");
                objectLock.ExitWriteLock(lockId);
            }
        }
Example #19
0
        public string Read(GStoreObjectIdentifier gStoreObjectIdentifier)
        {
            ReaderWriterLockSlim objectLock = GetObjectLock(gStoreObjectIdentifier);

            objectLock.EnterReadLock();
            try
            {
                string value = null;
                if (DataStore.TryGetValue(gStoreObjectIdentifier, out GStoreObject gStoreObject))
                {
                    value = gStoreObject.Value;
                }
                return(value);
            }
            finally
            {
                objectLock.ExitReadLock();
            }
        }
Example #20
0
        public void WriteReplica(GStoreObjectIdentifier gStoreObjectIdentifier, string newValue, string newServerId, int newVersion)
        {
            ReaderWriterLockSlim objectLock = GetObjectLock(gStoreObjectIdentifier);

            objectLock.EnterWriteLock();
            try
            {
                int    version  = GetObjectVersionNumber(gStoreObjectIdentifier);
                string serverId = GetObjectVersionServerWriter(gStoreObjectIdentifier);

                if (newVersion > version || newVersion == version && string.Compare(newServerId, serverId) < 0)
                {
                    _ = AddOrUpdate(gStoreObjectIdentifier, newValue);
                    SetObjectVersionNumber(gStoreObjectIdentifier, newVersion);
                }
            }
            finally
            {
                objectLock.ExitWriteLock();
            }
        }
Example #21
0
        public ICollection <GStoreObject> ReadAll()
        {
            ISet <GStoreObject> values = new HashSet <GStoreObject>();

            foreach (KeyValuePair <GStoreObjectIdentifier, ReaderWriterLockSlim> objectPair in ObjectLocks)
            {
                GStoreObjectIdentifier gStoreObjectIdentifier = objectPair.Key;
                ReaderWriterLockSlim   objectLock             = objectPair.Value;

                objectLock.EnterReadLock();
                try
                {
                    DataStore.TryGetValue(gStoreObjectIdentifier, out GStoreObject gStoreObject);
                    values.Add(gStoreObject);
                }
                finally
                {
                    objectLock.ExitReadLock();
                }
            }
            return(values);
        }
Example #22
0
        public void Write(GStoreObjectIdentifier gStoreObjectIdentifier, string newValue)
        {
            // Acquire lock on local object
            ReaderWriterLockSlim objectLock = GetObjectLock(gStoreObjectIdentifier);

            objectLock.EnterWriteLock();
            try
            {
                int version = GetAndIncrementObjectVersionNumber(gStoreObjectIdentifier);
                AddOrUpdateObjectVersionServerWriter(gStoreObjectIdentifier, connectionManager.SelfServerId);
                GStoreObject gStoreObject = AddOrUpdate(gStoreObjectIdentifier, newValue);

                _ = WriteReplicaController.ExecuteAsync(connectionManager, gStoreObject, version);
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
            }
            finally
            {
                objectLock.ExitWriteLock();
            }
        }
Example #23
0
        private ReadRecoveryReply ExecuteReadRecovery(ReadRecoveryRequest request)
        {
            GStoreObjectIdentifier gStoreObjectIdentifier = new GStoreObjectIdentifier(request.ObjectIdentifier.PartitionId, request.ObjectIdentifier.ObjectId);

            bool valid = !gStore.IsLocked(gStoreObjectIdentifier);

            ObjectDto objectDto = null;

            if (valid)
            {
                objectDto = new ObjectDto
                {
                    ObjectIdentifier = request.ObjectIdentifier,
                    Value            = gStore.Read(gStoreObjectIdentifier)
                };
            }

            return(new ReadRecoveryReply
            {
                Valid = valid,
                Object = objectDto
            });
        }
        public static async Task <string> ExecuteAsync(ConnectionManager connectionManager, GStoreObjectIdentifier gStoreObjectIdentifier)
        {
            string partitionId = gStoreObjectIdentifier.PartitionId;
            IImmutableSet <Server> partitionServers = connectionManager.GetAliveServers(partitionId);

            List <Task <ReadRecoveryReply> > tasks = new List <Task <ReadRecoveryReply> >();

            foreach (Server server in partitionServers)
            {
                Task <ReadRecoveryReply> t = ExecuteServerAsync(server.Stub, gStoreObjectIdentifier);
                tasks.Add(t);
            }

            foreach (Task <ReadRecoveryReply> t in tasks)
            {
                ReadRecoveryReply reply = await t;
                if (reply.Valid)
                {
                    return(reply.Object.Value);
                }
            }
            return(null);
        }
        private static async Task <ReadRecoveryReply> ExecuteServerAsync(MasterReplicaService.MasterReplicaServiceClient Stub, GStoreObjectIdentifier gStoreObjectIdentifier)
        {
            ReadRecoveryRequest request = new ReadRecoveryRequest
            {
                ObjectIdentifier = new ObjectIdentifierDto
                {
                    PartitionId = gStoreObjectIdentifier.PartitionId,
                    ObjectId    = gStoreObjectIdentifier.ObjectId
                }
            };

            return(await Stub.ReadRecoveryAsync(request));
        }
Example #26
0
        public static async Task <IDictionary <string, int> > ExecuteAsync(ConnectionManager connectionManager, GStoreObjectIdentifier gStoreObjectIdentifier)
        {
            // Get all replicas associated to this Partition
            IImmutableSet <Server> replicas = connectionManager.GetPartitionAliveReplicas(gStoreObjectIdentifier.PartitionId);

            IDictionary <string, Task <int> > lockTasks = new Dictionary <string, Task <int> >();

            foreach (Server replica in replicas)
            {
                lockTasks.Add(replica.Id, ExecuteReplicaAsync(replica.Stub, gStoreObjectIdentifier));
            }

            // Await for lock requests and save their values
            IDictionary <string, int> lockValues = new Dictionary <string, int>();

            foreach (KeyValuePair <string, Task <int> > lockTaskPair in lockTasks)
            {
                string replicaId = lockTaskPair.Key;
                try
                {
                    lockValues.Add(replicaId, await lockTaskPair.Value);
                }
                catch (Grpc.Core.RpcException e) when(e.StatusCode == Grpc.Core.StatusCode.Internal)
                {
                    connectionManager.DeclareDead(replicaId);
                }
            }
            return(lockValues);
        }
Example #27
0
        private static async Task <int> ExecuteReplicaAsync(MasterReplicaService.MasterReplicaServiceClient Stub, GStoreObjectIdentifier gStoreObjectIdentifier)
        {
            LockRequest lockRequest = new LockRequest
            {
                ObjectIdentifier = new ObjectIdentifierDto
                {
                    PartitionId = gStoreObjectIdentifier.PartitionId,
                    ObjectId    = gStoreObjectIdentifier.ObjectId
                }
            };

            LockReply lockReply = await Stub.LockAsync(lockRequest);

            return(lockReply.LockId);
        }
 internal static DataObjectIdentifier FromObjectIdentifier(GStoreObjectIdentifier objectIdentifier)
 {
     return(FromString(objectIdentifier.PartitionId, objectIdentifier.ObjectId));
 }
        private static GStoreObject CreateObject(DataObject dataObject)
        {
            GStoreObjectIdentifier gStoreObjectIdentifier = new GStoreObjectIdentifier(dataObject.ObjectIdentifier.PartitionId, dataObject.ObjectIdentifier.ObjectId);

            return(new GStoreObject(gStoreObjectIdentifier, dataObject.Value));
        }
Example #30
0
        public bool IsLocked(GStoreObjectIdentifier gStoreObjectIdentifier)
        {
            ReaderWriterLockEnhancedSlim objectLock = GetObjectLock(gStoreObjectIdentifier);

            return(objectLock.IsWriteLocked());
        }