locked
Bouncing some ideas around to detect thread timeout RRS feed

  • Question

  • May I prefix this with the following:  I am just starting to think about this and am just bouncing ideas around - currently you can think of this as pseudo code - I am absolutely sure this is a piece of work that will take many iterations - and I am not an expert in this area which is why I am posting it here and trying to get others to comment on my ideas, and to come up with better ones!!  ;-)  May I also thank you all for any time you spend looking at this and helping me to come up with a better way of doing things!

    Objective:

    What I am trying to achieve is a way to measure time spent within an "aws session" by all the subtasks in that particular session in order to determine when the aws timeout is about to throw my web services out because the overall "wall clock time" has exceeded 30 seconds.  Rather than have aws time out my session I want my services to gracefully timeout themselves.  I will use the ThresholdReached method to do the graceful timeouts.

    However, this is an environment where a single "aws session" ( I use that term loosely) can consist of many operations (mainly calls to a number of web services - I will call these SubTasks) some of which are synchronous, some of which are async..  in a multi-threading environment..


    namespace MSollicito.Api.Main
    {
      public class HourglassContainer : IContainer  //extend IContainer used elsewhere in app
      {

           // constructor here?

            public HourglassContainer()
            {
                base();  //look at what the container constructors take in as params????

               //not sure if I need a TimeManager in my container or not??

                builder.Register(c =>
                {
                    var timeClient = c.Resolve<ITimeClient>();
                    return new TimeManager(timeClient, APIAuthenticationConfig.Settings.Username, APIAuthenticationConfig.Settings.Password);
                }).As<ITimeManager>().SingleInstance();

            }



        private int _globalTimeValue = 30; //defaults to 30 at beginning (AWS max timeout), contains time remaining for this aws session

        private Object timeLock = new Object(); 

        //this will hold the time remaining for processing
        public static int GlobalTimeValue
        {
            get
            {

                return _globalTimeValue; //would we need read lock too??
            }
            set
            {
                lock (timeLock)
                {                 
                    _globalTimeValue =  value;
                    if (_globalTimeValue == 0)
                    {
                        //fire event letting all threads that need to be notified that they have timed out
                        ThresholdReached();
                    }
                }
            }
        }

        private int _globalSubTasks = 0;  //default to 0

        private Object taskLock = new Object(); 

        public static int GlobalSubTasks
        {
            get
            {

                return _globalSubTasks; //would we need read lock too??
            }
            set
            {
                lock (taskLock)
                {        
                    _globalSubTasks =  value;
                }
            }
        }

        private int _globalTaskTimeForSubTask = 5; //default to 5

        private Object taskTimeLock = new Object(); 

        //its a good idea to add as many GlobalSubTasks as you can before getting TaskTimeForSubTask
        public static int TaskTimeForSubTask
        {
            get
            {
                if (GlobalTimeValue > 0 && GlobalSubTasks > 1)
                {
                    _globalTaskTimeForSubTask = Math.Round(GlobalTimeValue / GlobalSubTasks);
                }
                else
                {
                    _globalTaskTimeForSubTask = 5;
                }
                return _globalTaskTimeForSubTask; //would we need read lock too??
            }
            set
            {
                lock (taskTimeLock)
                {        
                    _globalTaskTimeForSubTask =  value;
                }
            }
        }

        // Create new timer on the main thread
        private System.Timers.Timer TTTimer = new System.Timers.Timer();

        public void StartTiming()
        {

            // Begin timing.
            this.TTTimer.Interval = 1000; //1 sec
            this.TTTimer.Elapsed += new System.Timers.ElapsedEventHandler(TTTimer_Elapsed);
            this.TTTimer.Start();
        }

        void TTTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            string message = string.Format("Tick Generated from {0}", Thread.CurrentThread.Name);

            Console.Write(message);

            this.Dispatcher.Invoke((Action)delegate()
            {
                GlobalTimeValue--; //take one second off of the remaining time
            });
        }

        private Object subTaskAdd = new Object();

        //adding a new task means adding one to total globalsubtasks and finding a new value for TaskTime for the new task
        //this must of course be thread safe!
        public void NewTask()
        {
            lock (subTaskAdd)
            {

                GlobalSubTasks++;

             }

        }

        private Object completeTaskAdd = new Object();

        public void CompleteTask()
        {
            lock(completeTaskAdd)
            {
                GlobalSubTasks--;

            }
        }

        public event EventHandler ThresholdReached;

        protected virtual void OnThresholdReached(EventArgs e)
        {
            EventHandler handler = ThresholdReached;
            if (handler != null)
            {
                handler(this, e);
            }
        }

        //... and so on...

        // public and private methods here...
      }
    }

    I am very hopeful that I will get a lot of feedback and suggestions to help me come up with a good architecture for this.  If anyone knows of a piece of code that already does this kind of work or a pattern that exists already, please feel free to point that out - I am not about re-inventing any wheels that should already exist!

    Thanks so much!

                                                              
    Friday, March 3, 2017 2:04 AM

All replies

  • Hi msollicito,

    Based on your description, your case more related to web technology, For web ASP.NET, please using the following link:http://forums.asp.net

    Best regards,

    Kristin


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Monday, March 6, 2017 1:17 AM