global variables.

Clovertech Forums Read Only Archives Cloverleaf Tcl Library 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.