public void LoadSchema(string path) { var schema = _serviceContainer.SchemaPersistence.LoadSchema(path); if (schema != null) { foreach (var description in schema.CollectionsDescriptions) { ServerLog.LogInfo($"declaring collection {description.Key}"); RegisterType(new RegisterTypeRequest(description.Value, schema.ShardIndex, schema.ShardCount), null); } ShardIndex = schema.ShardIndex; ShardCount = schema.ShardCount; } }
public void LoadSchema(string path) { if (!File.Exists(path)) { return; } var json = File.ReadAllText(path); var schema = _jsonSerializer.Deserialize <Schema>( new JsonTextReader(new StringReader(json))); if (schema != null) { foreach (var typeDescription in schema.TypeDescriptions) { ServerLog.LogInfo($"registering type {typeDescription.FullTypeName}"); RegisterType(new RegisterTypeRequest(typeDescription, schema.ShardIndex, schema.ShardCount), null); } ShardIndex = schema.ShardIndex; ShardCount = schema.ShardCount; } }
private void ProcessTransactionRequest(TransactionRequest transactionRequest, IClient client) { // First try to acquire a write lock on all concerned data stores var typesToPut = transactionRequest.ItemsToPut.Select(i => i.FullTypeName).Distinct().ToList(); var typesToDelete = transactionRequest.ItemsToDelete.Select(i => i.FullTypeName).Distinct().ToList(); var types = typesToPut.Union(typesToDelete).Distinct().ToList(); if (types.Any(t => !DataStores.ContainsKey(t))) { throw new NotSupportedException("Type not registered"); } // do not work too hard if it's single stage if (transactionRequest.IsSingleStage) { ProcessSingleStageTransactionRequest(transactionRequest, client); return; } if (!AcquireWriteLock(client, types, transactionRequest.TransactionId)) { return; } Dbg.Trace($"S: lock acquired by all clients for transaction {transactionRequest.TransactionId}"); // Second register a durable delayed transaction. It can be cancelled later try { // check the conditions (in case of conditional update) int index = 0; foreach (var condition in transactionRequest.Conditions) { if (!condition.IsEmpty()) { var ds = DataStores[condition.TypeName]; ds.CheckCondition(transactionRequest.ItemsToPut[index].PrimaryKey, condition); } index++; } Dbg.Trace($"S: begin writing delayed transaction {transactionRequest.TransactionId}"); PersistenceEngine?.NewTransaction(new MixedTransaction { ItemsToDelete = transactionRequest.ItemsToDelete, ItemsToPut = transactionRequest.ItemsToPut }, true ); client.SendResponse(new ReadyResponse()); Dbg.Trace($"S: end writing delayed transaction {transactionRequest.TransactionId}"); } catch (CacheException e) { Dbg.Trace($"error in first stage:{e.Message} server {ShardIndex}"); client.SendResponse(new ExceptionResponse(e, e.ExceptionType)); // failed to write a durable transaction so stop here // unlock foreach (var type in types) { if (DataStores[type].Lock.IsWriteLockHeld) { DataStores[type].Lock.ExitWriteLock(); } } return; } catch (Exception e) { Dbg.Trace($"error in first stage:{e.Message} server {ShardIndex}"); client.SendResponse(new ExceptionResponse(e)); // failed to write a durable transaction so stop here // unlock foreach (var type in types) { if (DataStores[type].Lock.IsWriteLockHeld) { DataStores[type].Lock.ExitWriteLock(); } } return; } try { Dbg.Trace($"S: begin waiting for client go {transactionRequest.TransactionId}"); var answer = client.ShouldContinue(); Dbg.Trace($"S: end waiting for client go answer = {answer}"); if (answer.HasValue) // the client has answered { if (answer.Value) { // update the data in memory var dataRequests = transactionRequest.SplitByType(); foreach (var dataRequest in dataRequests) { if (!DataStores.ContainsKey(dataRequest.FullTypeName)) { throw new NotSupportedException( $"The type {dataRequest.FullTypeName} is not registered"); } DataStores[dataRequest.FullTypeName].ProcessRequest(dataRequest, client, null); } ServerLog.LogInfo( $"S: two stage transaction committed successfully on server {ShardIndex} {transactionRequest.TransactionId}"); } else { ServerLog.LogWarning( $"S: two stage transaction cancelled by client on server {ShardIndex} {transactionRequest.TransactionId}"); // cancel the delayed transaction PersistenceEngine?.CancelDelayedTransaction(); } } else // the client failed to answer in a reasonable delay (which is less than the delay to commit a delayed transaction ) { PersistenceEngine?.CancelDelayedTransaction(); } } catch (Exception e) { ServerLog.LogInfo($"error in the second stage of a transaction:{e.Message}"); } // unlock foreach (var type in types) { if (DataStores[type].Lock.IsWriteLockHeld) { DataStores[type].Lock.ExitWriteLock(); } } }