From d60a9515573fc09550ee5152132615555a4e1d21 Mon Sep 17 00:00:00 2001 From: Cyberboss Date: Tue, 12 Dec 2017 15:09:13 -0500 Subject: [PATCH] Revert "Merge pull request #455 from Cyberboss/FixLockup" This reverts commit a93120408ffaaf8d06ff84bc2e412ee29c02c0c9, reversing changes made to 6e820b89eed71e2a73cb85f7ed640606f3705a24. --- TGS.Interface/Components/Interop.cs | 2 +- TGS.Server/CallLogger.cs | 61 ------------ TGS.Server/EventID.cs | 4 - TGS.Server/Instance/Instance.cs | 19 +--- TGS.Server/Instance/Interop.cs | 149 ++++++++++++---------------- TGS.Server/Server.cs | 5 +- TGS.Server/TGS.Server.csproj | 1 - 7 files changed, 69 insertions(+), 172 deletions(-) delete mode 100644 TGS.Server/CallLogger.cs diff --git a/TGS.Interface/Components/Interop.cs b/TGS.Interface/Components/Interop.cs index 4ebf21bf90..80dc2c7c7c 100644 --- a/TGS.Interface/Components/Interop.cs +++ b/TGS.Interface/Components/Interop.cs @@ -12,7 +12,7 @@ namespace TGS.Interface.Components /// Called from /world/ExportService(command) /// /// The command to run - /// + /// on success, on failure [OperationContract] bool InteropMessage(string command); } diff --git a/TGS.Server/CallLogger.cs b/TGS.Server/CallLogger.cs deleted file mode 100644 index 7ddb7e409d..0000000000 --- a/TGS.Server/CallLogger.cs +++ /dev/null @@ -1,61 +0,0 @@ -using System; -using System.Collections.Generic; -using System.ServiceModel.Channels; -using System.ServiceModel.Description; -using System.ServiceModel.Dispatcher; - -namespace TGS.Server -{ - sealed class AddCallLoggerBehavior : IOperationBehavior - { - public void AddBindingParameters(OperationDescription operationDescription, BindingParameterCollection bindingParameters) - { - } - - public void ApplyClientBehavior(OperationDescription operationDescription, ClientOperation clientOperation) - { - clientOperation.ClientParameterInspectors.Add(new CallLogger()); - } - - public void ApplyDispatchBehavior(OperationDescription operationDescription, DispatchOperation dispatchOperation) - { - dispatchOperation.ParameterInspectors.Add(new CallLogger()); - } - - public void Validate(OperationDescription operationDescription) - { - } - } - sealed class CallLogger : IParameterInspector - { - static readonly IDictionary ActiveCalls = new Dictionary(); - - public void AfterCall(string operationName, object[] outputs, object returnValue, object correlationState) - { - lock (ActiveCalls) - --ActiveCalls[operationName]; - } - - public object BeforeCall(string operationName, object[] inputs) - { - lock (ActiveCalls) - { - string res = String.Empty; - foreach (var I in ActiveCalls) - { - if (I.Value > 0) - res += Environment.NewLine + I.Key + ": " + I.Value; - } - if (res != String.Empty) - { - res = String.Format("Starting call {0}. Warning: other calls in progress!{1}", operationName, res); - Server.Logger.WriteInfo(res, EventID.CallTracking, 0); - } - if (!ActiveCalls.ContainsKey(operationName)) - ActiveCalls.Add(operationName, 0); - ++ActiveCalls[operationName]; - return null; - } - } - } -} diff --git a/TGS.Server/EventID.cs b/TGS.Server/EventID.cs index 05043646ef..9981fd199f 100644 --- a/TGS.Server/EventID.cs +++ b/TGS.Server/EventID.cs @@ -331,9 +331,5 @@ namespace TGS.Server /// Warning: When a testmerge commit failed to be published /// ReferencePush = 7700, - /// - /// Info: When a call starts and another call hasn't completed - /// - CallTracking = 7800, } } diff --git a/TGS.Server/Instance/Instance.cs b/TGS.Server/Instance/Instance.cs index a5663c1bed..e28d58dc72 100644 --- a/TGS.Server/Instance/Instance.cs +++ b/TGS.Server/Instance/Instance.cs @@ -1,7 +1,7 @@ using System; +using System.Diagnostics; using System.IO; using System.ServiceModel; -using System.Threading; using TGS.Interface.Components; namespace TGS.Server @@ -104,23 +104,6 @@ namespace TGS.Server return Path.Combine(Config.Directory, path); } - /// - /// Dumps the status of all locks in the - /// - public void DumpLocks() - { - var res = Monitor.TryEnter(RepoLock); - string rb; - if (res) - { - rb = RepoBusy.ToString(); - Monitor.Exit(RepoLock); - } - else - rb = "UNKNOWN"; - Server.Logger.WriteWarning(String.Format("Started HandleCommand with others running! Active locks: Repo: {0}, Byond: {1}, Compiler: {2}, Topic: {3}, Config: {4}, Watchdog: {5}, Chat: {6}, this: {7}, restartLock: {8}, autoUpdateLock: {9}, RepoBusy: {10}", !res, CheckLocked(ByondLock), CheckLocked(CompilerLock), CheckLocked(topicLock), CheckLocked(configLock), CheckLocked(watchdogLock), CheckLocked(ChatLock), CheckLocked(this), CheckLocked(restartLock), CheckLocked(autoUpdateTimer), rb), EventID.CallTracking, LoggingID); - } - /// public string Version() { diff --git a/TGS.Server/Instance/Interop.cs b/TGS.Server/Instance/Interop.cs index b56bc27251..f24f3101f1 100644 --- a/TGS.Server/Instance/Interop.cs +++ b/TGS.Server/Instance/Interop.cs @@ -6,7 +6,6 @@ using System.Net; using System.Net.Sockets; using System.Text; using System.Threading; -using System.Threading.Tasks; using System.Web.Security; using TGS.Server.ChatCommands; using TGS.Interface; @@ -17,6 +16,7 @@ namespace TGS.Server //handles talking between the world and us sealed partial class Instance : ITGInterop { + object topicLock = new object(); const int CommsKeyLen = 64; string serviceCommsKey; //regenerated every DD restart @@ -65,8 +65,6 @@ namespace TGS.Server List ServerChatCommands; - int RunningCommandHandlers = 0; - void LoadServerChatCommands() { if (DaemonStatus() != DreamDaemonStatus.Online) @@ -90,91 +88,71 @@ namespace TGS.Server catch { } } - static bool CheckLocked(object o) - { - var res = Monitor.TryEnter(o); - if (res) - Monitor.Exit(o); - return !res; - } - //raw command string sent here via world.ExportService - Task HandleCommand(string cmd) + void HandleCommand(string cmd) { - return Task.Run(() => + var splits = new List(cmd.Split(' ')); + cmd = splits[0]; + splits.RemoveAt(0); + + bool APIValid; + lock (topicLock) { - if (Interlocked.Increment(ref RunningCommandHandlers) > 1) - DumpLocks(); - try - { - var splits = new List(cmd.Split(' ')); - cmd = splits[0]; - splits.RemoveAt(0); + APIValid = CheckAPIVersionConstraints(); + } - bool APIValid; - lock (topicLock) + if (!APIValid && cmd != SRAPIVersion) + return; //SPEAK THE LANGUAGE!!! + + switch (cmd) + { + case SRIRCBroadcast: + SendMessage("GAME: " + String.Join(" ", splits), MessageType.GameInfo); + break; + case SRKillProcess: + KillMe(); + break; + case SRIRCAdminChannelMessage: + SendMessage("RELAY: " + String.Join(" ", splits), MessageType.AdminInfo); + break; + case SRWorldReboot: + WriteInfo("World Rebooted", EventID.WorldReboot); + WriteCurrentDDLog("World rebooted"); + ServerChatCommands = null; + ChatConnectivityCheck(); + lock (CompilerLock) { - APIValid = CheckAPIVersionConstraints(); - } - - if (!APIValid && cmd != SRAPIVersion) - return; //SPEAK THE LANGUAGE!!! - - switch (cmd) - { - case SRIRCBroadcast: - SendMessage("GAME: " + String.Join(" ", splits), MessageType.GameInfo); - break; - case SRKillProcess: - KillMe(); - break; - case SRIRCAdminChannelMessage: - SendMessage("RELAY: " + String.Join(" ", splits), MessageType.AdminInfo); - break; - case SRWorldReboot: - WriteInfo("World Rebooted", EventID.WorldReboot); - WriteCurrentDDLog("World rebooted"); - ServerChatCommands = null; - ChatConnectivityCheck(); - lock (CompilerLock) - { - if (UpdateStaged) - { - UpdateStaged = false; - lock (topicLock) - { - GameAPIVersion = null; //needs updating - } - WriteInfo("Staged update applied", EventID.ServerUpdateApplied); - } - } - break; - case SRAPIVersion: + if (UpdateStaged) + { + UpdateStaged = false; lock (topicLock) { - try - { - GameAPIVersion = new Version(splits[0]); - if (!CheckAPIVersionConstraints()) - throw new Exception(); - } - catch - { - WriteWarning(String.Format("API version of the game ({0}) is incompatible with the current supported API versions (3.{2}.x.x). Interop disabled.", splits.Count > 1 ? splits[1] : "NULL", AllowedMajorAPIVersion), EventID.APIVersionMismatch); - GameAPIVersion = null; - break; - } + GameAPIVersion = null; //needs updating } - //This needs to be done asyncronously otherwise DD won't be able to process it, because it's waiting for THIS THREAD to return - ThreadPool.QueueUserWorkItem(_ => SendCommand(SCAPICompat)); - break; + WriteInfo("Staged update applied", EventID.ServerUpdateApplied); + } } - } - finally - { - Interlocked.Decrement(ref RunningCommandHandlers); - } - }); + break; + case SRAPIVersion: + lock (topicLock) + { + try + { + GameAPIVersion = new Version(splits[0]); + if (!CheckAPIVersionConstraints()) + throw new Exception(); + } + catch + { + WriteWarning(String.Format("API version of the game ({0}) is incompatible with the current supported API versions (3.{2}.x.x). Interop disabled.", splits.Count > 1 ? splits[1] : "NULL", AllowedMajorAPIVersion), EventID.APIVersionMismatch); + GameAPIVersion = null; + break; + } + } + //This needs to be done asyncronously otherwise DD won't be able to process it, because it's waiting for THIS THREAD to return + ThreadPool.QueueUserWorkItem(_ => SendCommand(SCAPICompat)); + break; + } } public string SendCommand(string cmd) @@ -283,11 +261,16 @@ namespace TGS.Server /// public bool InteropMessage(string command) { - HandleCommand(command).ContinueWith((t) => + try { - WriteWarning(String.Format("Handle command for \"{0}\" failed: {1}", command, t.Exception.ToString()), EventID.InteropCallException); - }, TaskContinuationOptions.OnlyOnFaulted); - return true; + HandleCommand(command); + return true; + } + catch(Exception e) + { + WriteWarning(String.Format("Handle command for \"{0}\" failed: {1}", command, e.ToString()), EventID.InteropCallException); + return false; + } } } } diff --git a/TGS.Server/Server.cs b/TGS.Server/Server.cs index 784f4fe7ba..42351977b7 100644 --- a/TGS.Server/Server.cs +++ b/TGS.Server/Server.cs @@ -4,7 +4,6 @@ using System.IO; using System.Reflection; using System.Security.Principal; using System.ServiceModel; -using System.ServiceModel.Description; using TGS.Interface; using TGS.Interface.Components; using TGS.Server.Security; @@ -336,9 +335,7 @@ namespace TGS.Server void AddEndpoint(ServiceHost host, Type typetype) { var bindingName = typetype.Name; - var endpint = host.AddServiceEndpoint(typetype, new NetNamedPipeBinding() { SendTimeout = new TimeSpan(0, 0, 30), MaxReceivedMessageSize = Definitions.TransferLimitLocal }, bindingName); - foreach (OperationDescription od in endpint.Contract.Operations) - od.OperationBehaviors.Add(new AddCallLoggerBehavior()); + host.AddServiceEndpoint(typetype, new NetNamedPipeBinding() { SendTimeout = new TimeSpan(0, 0, 30), MaxReceivedMessageSize = Definitions.TransferLimitLocal }, bindingName); var httpsBinding = new BasicHttpsBinding() { SendTimeout = new TimeSpan(0, 0, 40), diff --git a/TGS.Server/TGS.Server.csproj b/TGS.Server/TGS.Server.csproj index 14e9e076e2..83f970c8c1 100644 --- a/TGS.Server/TGS.Server.csproj +++ b/TGS.Server/TGS.Server.csproj @@ -81,7 +81,6 @@ -