/// <summary>添加Socket服务器</summary> /// <param name="server"></param> /// <returns>添加是否成功</returns> public virtual Boolean AttachServer(ISocketServer server) { if (Servers.Contains(server)) { return(false); } server.Name = String.Format("{0}{1}{2}", Name, server.Local.IsTcp ? "Tcp" : "Udp", server.Local.Address.IsIPv4() ? "" : "6"); // 内部服务器日志更多是为了方便网络库调试,而网络服务器日志用于应用开发 if (SocketLog != null) { server.Log = SocketLog; } server.NewSession += Server_NewSession; if (SessionTimeout > 0) { server.SessionTimeout = SessionTimeout; } if (Pipeline != null) { server.Pipeline = Pipeline; } server.StatSession = StatSession; server.StatSend = StatSend; server.StatReceive = StatReceive; server.LogSend = LogSend; server.LogReceive = LogReceive; server.Error += OnError; Servers.Add(server); return(true); }
protected override DocumentStore GetDocumentStore(Options options = null, [CallerMemberName] string caller = null) { // since we want server to survive between tests runs // we have to cheat a little bit // benchmark tests are divided into 2 phases: // 1. initialization // 2. actual test execution (this part is measured) var server = Server; if (Servers.Contains(server) == false) { Servers.Add(server); } if (options == null) { options = new Options(); } options.ModifyDatabaseRecord = record => record.Settings.Remove(RavenConfiguration.GetKey(x => x.Core.RunInMemory)); return(base.GetDocumentStore(options, caller)); }
protected virtual DocumentStore GetDocumentStore(Options options = null, [CallerMemberName] string caller = null) { try { lock (_getDocumentStoreSync) { options = options ?? Options.Default; var serverToUse = options.Server ?? Server; var name = GetDatabaseName(caller); if (options.ModifyDatabaseName != null) { name = options.ModifyDatabaseName(name) ?? name; } var hardDelete = true; var runInMemory = options.RunInMemory; var pathToUse = options.Path; if (runInMemory == false && options.ReplicationFactor > 1) { if (pathToUse == null) { // the folders will be assigned automatically } else { throw new InvalidOperationException($"You cannot set {nameof(Options)}.{nameof(Options.Path)} when, {nameof(Options)}.{nameof(Options.ReplicationFactor)} > 1 and {nameof(Options)}.{nameof(Options.RunInMemory)} == false."); } } else if (pathToUse == null) { pathToUse = NewDataPath(name); } else { hardDelete = false; runInMemory = false; } var doc = new DatabaseRecord(name) { Settings = { [RavenConfiguration.GetKey(x => x.Replication.ReplicationMinimalHeartbeat)] = "1", [RavenConfiguration.GetKey(x => x.Replication.RetryReplicateAfter)] = "1", [RavenConfiguration.GetKey(x => x.Core.RunInMemory)] = runInMemory.ToString(), [RavenConfiguration.GetKey(x => x.Core.ThrowIfAnyIndexCannotBeOpened)] = "true", [RavenConfiguration.GetKey(x => x.Indexing.MinNumberOfMapAttemptsAfterWhichBatchWillBeCanceledIfRunningLowOnMemory)] = int.MaxValue.ToString(), } }; if (pathToUse != null) { doc.Settings.Add(RavenConfiguration.GetKey(x => x.Core.DataDirectory), pathToUse); } if (options.Encrypted) { SetupForEncryptedDatabase(options, name, serverToUse, doc); } options.ModifyDatabaseRecord?.Invoke(doc); var store = new DocumentStore { Urls = UseFiddler(serverToUse.WebUrl), Database = name, Certificate = options.ClientCertificate }; options.ModifyDocumentStore?.Invoke(store); //This gives too much error details in most cases, we don't need this now store.RequestExecutorCreated += (sender, executor) => { executor.AdditionalErrorInformation += sb => sb.AppendLine().Append(GetLastStatesFromAllServersOrderedByTime()); }; store.Initialize(); if (options.CreateDatabase) { if (Servers.Contains(serverToUse)) { Servers.ForEach(server => CheckIfDatabaseExists(server, name)); } else { CheckIfDatabaseExists(serverToUse, name); } long raftCommand; try { if (options.AdminCertificate != null) { using (var adminStore = new DocumentStore { Urls = UseFiddler(serverToUse.WebUrl), Database = name, Certificate = options.AdminCertificate }.Initialize()) { raftCommand = adminStore.Maintenance.Server.Send(new CreateDatabaseOperation(doc, options.ReplicationFactor)).RaftCommandIndex; } } else { raftCommand = store.Maintenance.Server.Send(new CreateDatabaseOperation(doc, options.ReplicationFactor)).RaftCommandIndex; } } catch (ConcurrencyException) { var record = store.Maintenance.Server.Send(new GetDatabaseRecordOperation(name)); Assert.Equal(options.ReplicationFactor, record.Topology.ReplicationFactor); raftCommand = record.Etag; } Assert.True(raftCommand > 0); //sanity check if (Servers.Contains(serverToUse)) { var timeout = TimeSpan.FromMinutes(Debugger.IsAttached ? 5 : 1); AsyncHelpers.RunSync(async() => await WaitForRaftIndexToBeAppliedInCluster(raftCommand, timeout)); // skip 'wait for requests' on DocumentDatabase dispose Servers.ForEach(server => ApplySkipDrainAllRequestsToDatabase(server, name)); } else { ApplySkipDrainAllRequestsToDatabase(serverToUse, name); } } store.BeforeDispose += (sender, args) => { var realException = Context.GetException(); try { if (CreatedStores.TryRemove(store) == false) { return; // can happen if we are wrapping the store inside sharded one } DeleteDatabaseResult result = null; if (options.DeleteDatabaseOnDispose) { result = DeleteDatabase(options, serverToUse, name, hardDelete, store); } if (Servers.Contains(serverToUse) && result != null) { var timeout = options.DeleteTimeout ?? TimeSpan.FromSeconds(Debugger.IsAttached ? 5 : 1); AsyncHelpers.RunSync(async() => await WaitForRaftIndexToBeAppliedInCluster(result.RaftCommandIndex, timeout)); } } catch (Exception e) { if (realException != null) { throw new AggregateException(realException, e); } throw; } }; CreatedStores.Add(store); return(store); } } catch (TimeoutException te) { throw new TimeoutException($"{te.Message} {Environment.NewLine} {te.StackTrace}{Environment.NewLine}Servers states:{Environment.NewLine}{GetLastStatesFromAllServersOrderedByTime()}"); } }