message delay questions

Clovertech Forums Read Only Archives Cloverleaf Cloverleaf message delay questions

  • Creator
    Topic
  • #53381
    Mike Klemens
    Participant

      Greetings CloverTechers!

      I am trying to determine if it is possible to delay all messages going to a certain thread?  I was hoping there might be a bit of TCL code that I can use as a pre-proc to delay every message by a few seconds.

      Any ideas?

    Viewing 21 reply threads
    • Author
      Replies
      • #77492
        Kevin Crist
        Participant

          See if this helps any. Here is the argument example {SECS 90}.

          Code:

          #######################################################################################
          #######################################################################################
          #######################################################################################
          #
          # Name: tpsDelay
          # Purpose: This procedure sleeps for the number of seconds specified.
          #
          # UPoC type: tps
          # Args: tps keyedlist containing the following keys:
          #       MODE    run mode (”start”, “run” or “time”)
          #       MSGID   message handle
          #       ARGS    user-supplied arguments:
          #               The user supplied segment to remove is in the form of a keyed list
          #                 The key is SECS
          #                 The value is a number that = the number of seconds to sleep
          #
          # Returns: tps disposition list:
          #
          # John T. Zalesak 12/11/2008
          #
          #######################################################################################
          #######################################################################################
          #######################################################################################

          proc tpsDelay { args } {

          #######################################################################################
          # Setup some globals used
          #######################################################################################

          global HciConnName
          global HciSite

          #######################################################################################
          # Get the Connection Name for Error/Debug Messages
          #######################################################################################

          set myname “$HciConnName/[lindex [info level 1] 0]”

          #######################################################################################
          # Initialize Variables Used
          #######################################################################################

          set delaytime 0 ;# Seconds to Sleep, Default is 0
          set dispList {} ;# Disposition List Returned to Engine

          #######################################################################################
          # Load in the arguments we need that were passed from the caller
          #######################################################################################

          keylget args MODE mode             ;# The mode the engine called from
          keylget args ARGS.SECS delaytime ;# The seconds to sleep

          #######################################################################################
          # We only want to take action if called from the run mode
          #######################################################################################

          switch -exact — $mode {
          start {
          ;# Do Nothing
               }

          run {
          echo n n
          echo “Site: $HciSite  Connection/tps: $myname”
          echo “Going to sleep for $delaytime seconds.
               — [clock format [clock scan “today”] -format “%Y-%m-%d %H:%M:%S”]”
          sleep $delaytime ;# User Specified Sleep Time in Secs
          echo “Done Sleeping!”
          echo n n
          set mh [keylget args MSGID] ;# Get message handle from args
             set dispList [list “CONTINUE $mh”] ;# Initialize to good message

          }

               time {
          ;# Do Nothing
                 }
                 
               shutdown {
          ;# Do Nothing
              }
          } ;# End Switch

          return $dispList

          } ;# End Proc

        • #77493
          Mike Klemens
          Participant

            Thanks for posting that!  However, I was told that the “sleep” command pauses the entire process and this could potientally impact any other threads running under this same process – is there another way to do this without using “sleep”?

          • #77494
            Kevin Crist
            Participant

              ahh, i see. and yes it does the process. Have you looked into message throttling? i have never used it so it may or may not apply.

            • #77495
              Jeff Dinsmore
              Participant

                I would also be concerned with just sleeping/pausing  a certain number of seconds.

                If another message arrives from your source system during the time the previous one is “sleeping”, it would then wait for the balance of the previous messages sleepy time as well as its own. So, your delay could be compounded on an interface with fairly frequent messages.

                But, my primary question would be: “Why do you need the delay in the first place?”

                I’ve used message deferral in a few situations, but it’s never been because of a few seconds timing issue – it’s always been to accommodate some sort of system limitation.

                For example, our clinical system sends diet orders with a future date. The dietary system can’t handle the future dates (it immediately cancels the active order and replaces it with the future one), so we put the future order in a SQLite database, then wait to send it until its scheduled start time.

                Jeff Dinsmore
                Chesapeake Regional Healthcare

              • #77496
                Mike Klemens
                Participant

                  The reason that I am faced with looking into all of this is as follows:

                  We have a system that we are sending ADT and SIU messages to.  This system needs these messages on different ports.  We have one thread setup for ADT and another setup for SIU.

                  Our sending system sends the ADT and SIU messages very quickly, one after the other – and we send them on to the receiving system – they seem to arrive at just about the same exact time – so close together that sometimes the receiving system processes the SIU before they get the ADT and that is a problem for them.

                  Because of that, we need a way to delay all SIU messages by a few seconds, so that we are sure the ADT is received and processed first.

                • #77497
                  Jerry Tilsley
                  Participant

                    What I have done is similar instances is to write the messages I need to hold to a SQLite database with current timestamp.  The database would include a field that indicates if the message has been sent or not.  Then I would have another thread read the database on a timed schedule and send messages that have been queued for a minimum amount of time, in my case a couple hours, but you could easily shorten to minutes as to not delay the messages to long.

                  • #77498
                    Jim Kosloskey
                    Participant

                      Another option is to ask the receiving system to delay their acknowledtment of the SIU messages for a given amount of time or to provfide a ‘suspense’ process – they should be responsible for the handling in this case in my opinion.

                      email: jim.kosloskey@jim-kosloskey.com 29+ years Cloverleaf, 59 years IT - old fart.

                    • #77499
                      Richard Hart
                      Participant

                        We use this method for delaying – for similar reasons – but our delays are longer. This would work for seconds, but is simpler for a minute.

                        Add one extra thread that replaces the outbound thread. This new thread writes OB messages to a repository with date stamped files.  The thread also reads the repository and picks up files older than a minute, loads the messages  and delivers them.

                      • #77500
                        Mike Klemens
                        Participant

                          Thank you all for your comments.  I wanted to send out a brief update and also ask another question.

                          I ended up using Kevin’s code snippit and have a simple tps proc on my outbound thread that delays sending the scheduling messages for a few seconds.

                          We run this thread in its own process because we were worried the sleep command would have an impact on other code and threads in the same process.

                          However, I saw an option in any of the TPS selectors where you can “Run in a Sub-Thread” – are any of you familiar with this?

                        • #77501
                          Jacques Talbot
                          Participant

                            I found a clean way to delay messages. You must put the outbound tread on hold, and call the script in ob_tps that will release one messages latter with the unix “at” command. It take the parameters: DELAY UNIT and HCIPROCESS

                            set gVersion:gTpsDelayMsg 1.0
                            proc gTpsDelayMsg { args } {
                            global HciConnName
                            [code]
                            set gVersion:gTpsDelayMsg 1.0
                            proc gTpsDelayMsg { args } {
                            global HciConnName

                          • #77502
                            Dustin Sayes
                            Participant

                              Attempting to use the script posted by Jacques but I get TCL 203 error.

                            • #77503
                              Jacques Talbot
                              Participant

                                We are on AIX 6.1 and we have Cloverleaf 6.1

                                May be you have an older version of Cloverleaf ?

                              • #77504
                                Dustin Sayes
                                Participant

                                  using 6.0.2

                                  Does your script contain features that only work on 6.1?

                                  I know the hcicmd is normal command…

                                  I don’t understand this part of your script:

                                  $HciConnName prls_obd 1′ > /dev/null 2> /dev/null” | at now + $delay $unit > /dev/null 2> /dev/null

                                • #77505
                                  aaron kaufman-moore
                                  Participant

                                    Mike Klemens wrote:

                                    Thanks for posting that!

                                  • #77506
                                    Charlie Bursell
                                    Participant

                                      Aaron:  You are correct, the sleep command affects the whole process and other blocking commands such as at, etc cab be unreliable since they depend on a continuous running process which we do not have.

                                      One way to accomplish what you want – not very pretty but works.

                                      Set up a timer thread that runs periodically. Feed the thread you wish to delay with that one.  Have the timer thread send a token when it fires.  Anything would do that you would recognize in the other thread.

                                      In the OB thread set a global or namespace value with the time it was last released – set to 0 to start.  Also set up a saved message handle buffer – set to empty to start.   Each time you receive a token compare global time with current time.  If you have messages in the saved buffer end them all.  Be sure and KILL the token message handle.

                                      Whenever a message is received in the OB thread, simple save the message handle to the message handle buffer and return the empty string.  This makes sure the messages remain in State 10 if shutdown occurs.

                                      When it is time to send, update the time last released and CONTINUE all of the message handles in the message buffer.  Be sure and set message buffer to empty string and KILL token message handle

                                      I hope it makes sense

                                      As I said not very elegant but I have used it and it works.

                                    • #77507
                                      Charlie Bursell
                                      Participant

                                        Aaron:  You are correct, the sleep command affects the whole process and other blocking commands such as at, etc cab be unreliable since they depend on a continuous running process which we do not have.

                                        One way to accomplish what you want – not very pretty but works.

                                        Set up a timer thread that runs periodically. Feed the thread you wish to delay with that one.  Have the timer thread send a token when it fires.  Anything would do that you would recognize in the other thread.

                                        In the OB thread set a global or namespace value with the time it was last released – set to 0 to start.  Also set up a saved message handle buffer – set to empty to start.   Each time you receive a token compare global time with current time.  If you have messages in the saved buffer end them all.  Be sure and KILL the token message handle.

                                        Whenever a message is received in the OB thread, simple save the message handle to the message handle buffer and return the empty string.  This makes sure the messages remain in State 10 if shutdown occurs.

                                        When it is time to send, update the time last released and CONTINUE all of the message handles in the message buffer.  Be sure and set message buffer to empty string and KILL token message handle

                                        I hope it makes sense

                                        As I said not very elegant but I have used it and it works.

                                      • #77508
                                        Charlie Bursell
                                        Participant

                                          Sorry about the double send.  This internet suks!

                                        • #77509
                                          Jacques Talbot
                                          Participant

                                            Dustin Sayes wrote:

                                            using 6.0.2

                                            Does your script contain features that only work on 6.1?

                                            I know the hcicmd is normal command…

                                            I don’t understand this part of your script:

                                            $HciConnName prls_obd 1′ > /dev/null 2> /dev/null” | at now + $delay $unit > /dev/null 2> /dev/null

                                            Let me explain here is the complete line:

                                            Code:

                                            exec echo “hcicmd -p $HciProcess -s $HciSite -c ‘$HciConnName prls_obd 1’ > /dev/null 2> /dev/null” | at now + $delay $unit > /dev/null 2> /dev/null


                                            I ask tcl to execute the script in a shell

                                            The script start with an echo of a command that is piped for input to the at command.

                                            at will execute later :

                                            “hcicmd -p $HciProcess -s $HciSite -c ‘$HciConnName prls_obd 1’ > /dev/null 2> /dev/null”

                                            The at command usualy return the log and err with mail, so I redirected every output to /dev/null

                                            The hcicmd release one message with prls_obd .

                                            I think older 6.1 version prls_obd didn”t had a parameter, it was releasing everything that were on hold in the outbound.

                                          • #77510
                                            Jacques Talbot
                                            Participant

                                              Charlie Bursell wrote:

                                              Aaron:

                                            • #77511
                                              Charlie Bursell
                                              Participant

                                                Perhaps you are correct but the at command as I understand it will run the process at a given time.  It would probably be OK if only one thread used that process

                                              • #77512
                                                Jacques Talbot
                                                Participant

                                                  Charlie Bursell wrote:

                                                  Perhaps you are correct but the at command as I understand it will run the process at a given time.

                                                • #77513
                                                  David Barr
                                                  Participant

                                                    Jeff’s idea of putting the messages in a database will work well. I’ve done something similar where we write the messages out to files, then we use a fileset-local inbound thread to read the files back in. We use a dirparse proc that filters out the files that have a modification time that’s more recent than the delay that we want to introduce.

                                                Viewing 21 reply threads
                                                • The forum ‘Cloverleaf’ is closed to new topics and replies.