From 21176a3a901dd2190a1847acf576b938c0885e23 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 13 Aug 2014 22:38:27 +0100 Subject: Terminate 'nothing' behaviour (and potentially others) by signalling using an event rather than polling connection state every 100ms This kind of polling is very expensive with many bots/polling threads and appears to be the primary cause of bot falloff from the client end at higher loads. Where inbound packet threads can't run in time due to contention and simulator disconnect timeout occurs. --- .../Tools/pCampBot/Behaviours/AbstractBehaviour.cs | 14 ++++-- OpenSim/Tools/pCampBot/Behaviours/NoneBehaviour.cs | 10 ++++ .../Tools/pCampBot/Behaviours/PhysicsBehaviour.cs | 2 + OpenSim/Tools/pCampBot/Bot.cs | 58 ++++++++++------------ OpenSim/Tools/pCampBot/Interfaces/IBehaviour.cs | 8 +++ 5 files changed, 56 insertions(+), 36 deletions(-) (limited to 'OpenSim/Tools/pCampBot') diff --git a/OpenSim/Tools/pCampBot/Behaviours/AbstractBehaviour.cs b/OpenSim/Tools/pCampBot/Behaviours/AbstractBehaviour.cs index 9bc8512..c1ba36b 100644 --- a/OpenSim/Tools/pCampBot/Behaviours/AbstractBehaviour.cs +++ b/OpenSim/Tools/pCampBot/Behaviours/AbstractBehaviour.cs @@ -29,11 +29,12 @@ using OpenMetaverse; using System; using System.Collections.Generic; using System.Linq; +using System.Threading; using pCampBot.Interfaces; namespace pCampBot { - public class AbstractBehaviour : IBehaviour + public abstract class AbstractBehaviour : IBehaviour { /// /// Abbreviated name of this behaviour. @@ -44,13 +45,20 @@ namespace pCampBot public Bot Bot { get; protected set; } - public virtual void Action() {} + public abstract void Action(); + + public virtual void Interrupt() {} + + protected AutoResetEvent m_interruptEvent = new AutoResetEvent(false); public virtual void Initialize(Bot bot) { Bot = bot; } - public virtual void Close() {} + public virtual void Close() + { + Interrupt(); + } } } diff --git a/OpenSim/Tools/pCampBot/Behaviours/NoneBehaviour.cs b/OpenSim/Tools/pCampBot/Behaviours/NoneBehaviour.cs index 9a3075c..4a7237c 100644 --- a/OpenSim/Tools/pCampBot/Behaviours/NoneBehaviour.cs +++ b/OpenSim/Tools/pCampBot/Behaviours/NoneBehaviour.cs @@ -43,5 +43,15 @@ namespace pCampBot AbbreviatedName = "n"; Name = "None"; } + + public override void Action() + { + m_interruptEvent.WaitOne(); + } + + public override void Interrupt() + { + m_interruptEvent.Set(); + } } } \ No newline at end of file diff --git a/OpenSim/Tools/pCampBot/Behaviours/PhysicsBehaviour.cs b/OpenSim/Tools/pCampBot/Behaviours/PhysicsBehaviour.cs index 6fd2b7c..98ab931 100644 --- a/OpenSim/Tools/pCampBot/Behaviours/PhysicsBehaviour.cs +++ b/OpenSim/Tools/pCampBot/Behaviours/PhysicsBehaviour.cs @@ -82,6 +82,8 @@ namespace pCampBot { if (Bot.ConnectionState == ConnectionState.Connected) Bot.Client.Self.Jump(false); + + base.Close(); } private string[] readexcuses() diff --git a/OpenSim/Tools/pCampBot/Bot.cs b/OpenSim/Tools/pCampBot/Bot.cs index bd5eb81..fd9ae3f 100644 --- a/OpenSim/Tools/pCampBot/Bot.cs +++ b/OpenSim/Tools/pCampBot/Bot.cs @@ -192,15 +192,15 @@ namespace pCampBot public bool AddBehaviour(IBehaviour behaviour) { - lock (Behaviours) - { - if (!Behaviours.ContainsKey(behaviour.AbbreviatedName)) - { - behaviour.Initialize(this); - Behaviours.Add(behaviour.AbbreviatedName, behaviour); + Dictionary updatedBehaviours = new Dictionary(Behaviours); - return true; - } + if (!updatedBehaviours.ContainsKey(behaviour.AbbreviatedName)) + { + behaviour.Initialize(this); + updatedBehaviours.Add(behaviour.AbbreviatedName, behaviour); + Behaviours = updatedBehaviours; + + return true; } return false; @@ -208,18 +208,17 @@ namespace pCampBot public bool RemoveBehaviour(string abbreviatedName) { - lock (Behaviours) - { - IBehaviour behaviour; + Dictionary updatedBehaviours = new Dictionary(Behaviours); + IBehaviour behaviour; - if (!Behaviours.TryGetValue(abbreviatedName, out behaviour)) - return false; + if (!updatedBehaviours.TryGetValue(abbreviatedName, out behaviour)) + return false; - behaviour.Close(); - Behaviours.Remove(abbreviatedName); + behaviour.Close(); + updatedBehaviours.Remove(abbreviatedName); + Behaviours = updatedBehaviours; - return true; - } + return true; } private void CreateLibOmvClient() @@ -279,24 +278,17 @@ namespace pCampBot { while (ConnectionState == ConnectionState.Connected) { - lock (Behaviours) + foreach (IBehaviour behaviour in Behaviours.Values) { - foreach (IBehaviour behaviour in Behaviours.Values) - { // Thread.Sleep(Random.Next(3000, 10000)); - - // m_log.DebugFormat("[pCAMPBOT]: For {0} performing action {1}", Name, b.GetType()); - behaviour.Action(); - } + + // m_log.DebugFormat("[pCAMPBOT]: For {0} performing action {1}", Name, b.GetType()); + behaviour.Action(); } - - // XXX: This is a really shitty way of yielding so that behaviours can be added/removed - Thread.Sleep(100); } - lock (Behaviours) - foreach (IBehaviour b in Behaviours.Values) - b.Close(); + foreach (IBehaviour b in Behaviours.Values) + b.Close(); } /// @@ -305,9 +297,9 @@ namespace pCampBot public void Disconnect() { ConnectionState = ConnectionState.Disconnecting; - -// if (m_actionThread != null) -// m_actionThread.Abort(); + + foreach (IBehaviour behaviour in Behaviours.Values) + behaviour.Interrupt(); Client.Network.Logout(); } diff --git a/OpenSim/Tools/pCampBot/Interfaces/IBehaviour.cs b/OpenSim/Tools/pCampBot/Interfaces/IBehaviour.cs index 0ed4825..660c630 100644 --- a/OpenSim/Tools/pCampBot/Interfaces/IBehaviour.cs +++ b/OpenSim/Tools/pCampBot/Interfaces/IBehaviour.cs @@ -51,6 +51,14 @@ namespace pCampBot.Interfaces void Initialize(Bot bot); /// + /// Interrupt the behaviour. + /// + /// + /// This should cause the current Action call() to terminate if this is active. + /// + void Interrupt(); + + /// /// Close down this behaviour. /// /// -- cgit v1.1