global variables.

  • Creator
    Topic
  • #49960
    Kevin Crist
    Participant

    How can I access from within a tps tclproc the global variable for the current site my tclproc is running in?

    Thanks!

Viewing 22 reply threads
  • Author
    Replies
    • #64261

      Here is a common line from many tps scripts:

      Code:

      global HciSite HciSiteDir HciProcessesDir HciConnName HciRootDir ibdir

      You can then access the variable in the normal way like maybe “puts $HciSiteDir”.

      -- Max Drown (Infor)

    • #64262
      Charlie Bursell
      Participant

      If you remember that the global area is simply a namespace you can access them without declaring as global as long as you provide the full path to the variable.

      For example: $::HciSiteDir

    • #64263
      Todd Horst
      Participant

      So does each thread have thier own global section? Can you share globals between threads, processes, sites? At what level does tcl get loaded and therefore is the ceiling for sharing globals?

      I created 2 scripts to share a global between two threads and it didnt work. Here was my setup

      Script 1:

      global testvar

      set testvar “Some Value”

      Script 2:

      global testvar

      echo $testvar

      I would expect this to spit out “Some Value”, instead i get a tcl error saying its an undefined variable.

      Any ideas?

    • #64264
      Charlie Bursell
      Participant

      Each interpreter has it’s own global area.  Anything defined outside of a process is, by definition global.  A running engine has three interpreters, one for the IB Protocol Thread, one for the OB Protocol Thread and another for the Xlate Thread.  SO as long as a proc shares the same interpreter it can share globals.

      This is basic Tcl stuff covered quite well in Brent Welch’s book

    • #64265
      Todd Horst
      Participant

      Im able to set a variable and use it in two procs if its set up like this, all in the same file:

      set var1 “some value”

      proc 1 {} {

      global var1

      echo $var1

      }

      proc 2 {} {

      global var1

      echo $var1

      }

      I then place these procs in the TPS Outbound Data field. Im guessing this works because everytime it runs the proc its sourcing the file and therefore defining the var1 variable no matter which proc it wants to call.

      What im looking for is a global variable that is maintained. So for example. 3 threads could share the same variable globally, but all 3 threads have a proc from a different file. If the variable didnt exitst yet any of the three could create it, but once it existed, any of the three could access it.

      So here is a more accurate description of my scenario. Each time a message goes through it should echo “some value”, and it will for test1, but for test2 it will say its undefined:

      File1:

      set testvar2 “some value”

      proc test1 { args } {

         keylget args MODE mode               ;# Fetch mode

      global testvar2

         set dispList {} ;# Nothing to return

         switch -exact — $mode {

             run {

      echo $testvar2

         # ‘run’ mode always has a MSGID; fetch and process it

                 keylget args MSGID mh

                 lappend dispList “CONTINUE $mh”

             }

       

         }

         return $dispList

      }

      file 2:

      proc test2 { args } {

         keylget args MODE mode               ;# Fetch mode

      global testvar2

         set dispList {} ;# Nothing to return

         switch -exact — $mode {

                  run {

      echo $testvar2

         # ‘run’ mode always has a MSGID; fetch and process it

                 keylget args MSGID mh

                 lappend dispList “CONTINUE $mh”

             }

         }

         return $dispList

      }

    • #64266
      Charlie Bursell
      Participant

      Take a look at the recover_33 procs to see how globals are shared there

    • #64267
      Todd Horst
      Participant

      Right, and thats how i started my scripts initially but i cannot get it to work.

      If you take the following 2 procs, save them to a file (can be one or two files) then create 2 threads. Then on the first thread on the outbound tab set tps outbound data proc to the 1st proc and on the 2nd thread set same field to the 2nd proc. Now start up the first thread. Now start up the second thread.

      It will give you a “can’t read “gvar”: no such variable'”.

      Any ideas on how to get it to work would be nice, If you can fix the code that would be better…

      proc test1 { args } {

         keylget args MODE mode             ;# Fetch mode

         global gvar

         set dispList {} ;# Nothing to return

         set gvar “heyyou”

         switch -exact — $mode {

             start {

       echo $gvar

             }

             run {

                 keylget args MSGID mh

                 lappend dispList “CONTINUE $mh”

             }

                 

             shutdown {

         echo $gvar

      }

         }

         return $dispList

      }

      proc test2 { args } {

         keylget args MODE mode         ;# Fetch mode

         set dispList {} ;# Nothing to return

         global gvar

         switch -exact — $mode {

             start {

                 echo $gvar

             }

             run {

         # ‘run’ mode always has a MSGID; fetch and process it

                 keylget args MSGID mh

                 lappend dispList “CONTINUE $mh”

             }

             

             shutdown {

         echo $gvar

      }

         }

         return $dispList

      }

    • #64268
      Charlie Bursell
      Participant

      Ah, but that is your problem, two thread.  I said there are at least three interpreters, one for each Protocol Thread and one for the Xlate thread.  I you define two threads, each will have it’s own interpreter.  You cannot share globals across interpreters.

    • #64269
      Todd Horst
      Participant

      Okay, That was my underlining question. At what level the tcl runs at, and your answer is that each thread has 3 instances of tcl running, IB OB and XLATE.

      So a multiple thread variable is not possible. This is fine, i was just curious if it was possible.

      My main reason if everyone was curious is that i wanted to share an odbc persistent connection to a server among several threads. This way we could limit the connections coming out, and maximizing a connections throughput instead of many small (sometimes inactive) odbc connections.

      Thanks charlie

    • #64270
      Kevan Riley
      Participant

      There are two ways I know of to “share” information (like an ODBC handle) between threads.  One is to write it to a file, and read it from there.  You would need to clean up your file when you close the handle or in teh shutdown part of the thread that creates the handle.  the other is through message metadata USERDATA.  You can use the message to carry your information to the next thread by storing it in the USERDATA and then reading it in the dest. thread.

      Kevan Riley

      AHS-IS

    • #64271
      Todd Horst
      Participant

      yeh, i was thinking more your second approach. Set up a odbc thread that connected to a server and then send all my messages to that thread. Routing to specific procs would be determined by its meta data.

      So the message comes in, i read meta data, call a sub proc in a namespace that write it to the correct table, or performs and needed modifications before writting to a common table…whatever the case demanded.

      The benifit of the impossibility of a site global is that it would be much more orginized and readable. So we are able to have each thread do specific tasks for its needs.

      I realize the true global could present issues with variable overwrites, but with some management and orginization thats pretty easily solved. Not to mention that most people that would globals would understand the concept and its complications.

      Besides any other language you look at his the same issue, which really i wouldnt call and issue, but rather a feature.

      Thanks for your suggestion Kevan.

    • #64272
      Kevan Riley
      Participant

      If you wanted to get really clever you could craft a proc that hides the metadata reading and writing and make it function more or less like the “global” command.  Especially since you are mostly just reading it, and not changing it.  Make it a proc in a library and “package require” it.  That would hide all of the “ugliness” of putting and getting to/from USERDATA.  You would have to pass the message handle, a key name, and optionally a value to set.  The return value would be whatever is set.

      eg. something like this

      # set ODBC connection handle to metatdata

      # where:

      #   $mh is your message handle

      #   ODBC_CH is you key in the metadata USERDATA

      #   $ODBC_ch is the connection handle variable

      set null [MetaGlobal $mh ODBC_CH $ODBCch]

      # read ODBC connection handle from metadata

      set ODBCch [MetaGlobal $mh ODBC_CH]

      if you want to do it right and handle errors, make the call something like this:

      if {[catch {MetaGlobal $mh ODBC_CH $ODBCch} result]} {

       echo “Error: MetaGlobal store failed with error: $result”

      # handle error!

      }

      unset result

      and

      if {[catch {MetaGlobal $mh ODBC_CH} result]} {

       echo “Error: MetaGlobal fetch failed with error: $result”

      # handle error!

      } else {

       set ODBCch $result

      }

      unset result

      Kevan Riley

      AHS-IS

    • #64273
      Kevan Riley
      Participant

      The previous is an example of calling the proc, not the proc its self,

    • #64274
      Troy Morton
      Participant

      Is there anywhere that all the global Tcl variables available in the engine are documented?  I couldn’t find anything in the manuals when searching for “global HciConnName”.  It would be nice to have a table of all the global variables established by the engine interpreter and what they contain.

      Troy

    • #64275
      Todd Horst
      Participant

      Code:

      proc globalpat {args} {
             foreach pattern $args {
                 set varnames [info globals $pattern]
                 if {[llength $varnames] != 0} {
      echo $varnames
                 }
             }
         }

      globalpat *

      Found this on the internet-> i agree it should be documented. i was looking for a way now to retrieve the threads process name, thought it would be in global, but it is not.

    • #64276
      Troy Morton
      Participant

      Here is how I’ve been able to get the Cloverleaf Engine process name from within Tcl.

    • #64277
      Russ Ross
      Participant

      Troy Morton asked:

      Is there anywhere that all the global Tcl variables available in the engine are documented? [code]Is there anywhere that all the global Tcl variables available in the engine are documented?

      Russ Ross
      RussRoss318@gmail.com

    • #64278
      Charlie Bursell
      Participant

      Why jump through all these hoops?  🙂

      set HciProcess  [file tail [pwd]]   from a running engine

      grep protocol NetConfig | cut ……

      Troy Morton wrote:

      Here is how I’ve been able to get the Cloverleaf Engine process name from within Tcl.

    • #64279
      Troy Morton
      Participant

      I knew you’d jump in with a one-liner, Charlie.

    • #64280
      Charlie Bursell
      Participant

      We didn’t make that a global because it is readily available via the command I gave you.

      Of course you are free to modify $HCIROOT/tcl/lib/cloverleaf/init.tcl at you site and add it  😀

    • #64281
      Troy Morton
      Participant

      Charlie, did you notice your last post was your 666th post.

    • #64282
      Charlie Bursell
      Participant

      I’m a pretty spooky guy  😈  😈

    • #64283
      Kevan Riley
      Participant

      try:

      puts “[info globals]”

      Kevan Riley

      AHS-IS

Viewing 22 reply threads
  • The forum ‘Tcl Library’ is closed to new topics and replies.

Forum Statistics

Registered Users
5,042
Forums
28
Topics
9,200
Replies
34,023
Topic Tags
267