Upoc tcl open and write multiple files based upon max file size limit

Homepage Clovertech Forums Cloverleaf Upoc tcl open and write multiple files based upon max file size limit

  • Creator
    Topic
  • #117451
    Bill Pitts
    Participant

    Hi

    Since increase Covid reporting requirements – we’re having issues with our ELR results file to state DPH exceeding DPH max file size limit.

    We process using upoc protocol and advanced scheduler on outbound thread.

    HL7 msgs from lab stored in tmp file; upoc reads temp file and writes output on timer.

    Header/trailer added to output file

    I need to split the output into multiple files if file max (1.5Mb) exceeded.

    I can identify number of output files needed by dividing the input file size by max file limit (and adding 1 for “overages”) but I’m having trouble opening the proper number of output channels.  I’d then write the transactions from the input file based on transaction count (I have a pretty good estimate of how many transactions I can send on output).

    We’ve also looked into setting up alert on file size and calling tclproc to split file but worried that approach might truncate data msgs.

    Each HL7 msg starts with MSH segment and ends with SPM segments

    We’re running CLV 19.1.1 on AIX

    Thanks

     

    Bill

Viewing 2 reply threads
  • Author
    Replies
    • #117456
      Charlie Bursell
      Participant

      If you are creating tmp files using UPoC why not simply create multiple files?

      You could append to a file until max size is reached and then create a new one.  I would set the high level to about 10% less than max just to be sure.  Size the file prior to appending using the file size command and compare to a global max size.

      You could create an OB thread that uses fileset/local  and then when timer goes off move the tmp files to the fileset/local directory and let the engine handle the load.

      Be sure and move do not copy.  Move is an atomic operation so the engine will not try to read files before they are in the fileset/local directory

    • #117458
      Bill Pitts
      Participant

       

       

      Current tclproc, that successfully processes one nightly file, below:

      #    *********************************************************************
      #    on RUN mode:    Appends msgs to temp file TUFTS_MDPH_ELR_tmp_in.txt
      #
      #                    Make sure to set Process name to “softlab” for TEST/PROD
      #
      #    on TIMER mode:  Writes header, reads/write msgs from temp file to
      #                    TUFTS_MDPH_ELR_OUT.yyyymmddhhmm file, writes trailer
      #
      #                    Deletes .tmp file upon completion
      #
      #    ***********************************************************************
      #
      #———————————————————————————–
      # Modifications:
      #
      #  date   init     mod desc
      #
      #
      #———————————————————————————–

      proc tpsSoftlab_MDPHbatchAuto { args } {

      keylget args MODE mode              ;# Fetch mod

      set dispList {}                ;# Nothing to return

      #Make sure to set Process name to “softlab” for TEST/PROD
      set Process “softlab”
      #set Process “testing”
      set Outpath “/mdph_to_send/”

      switch -exact — $mode {
      start {
      # startup stuff
      # N.B.: there may or may not be a MSGID key in args
      }

      run {
      # ‘run’ mode always has a MSGID; fetch and process it
      keylget args MSGID mh
      set msg [msgget $mh]

      # Get rid of all \x1c and \x0b
      regsub -all — {[\x1c\x0b]} $msg {} msg

      #Get the time in system seconds
      set systemTime [clock seconds]
      #Set the time using the hour, minute and second descriptors.
      set CurDate [clock format $systemTime -format {%Y%m%d}]
      set CurDateTime [clock format $systemTime -format {%Y%m%d%H%M}]

      # set directory path
      set root_path [exec env HCIROOT]
      set site_path [exec env HCISITEDIR]
      set subdir “exec/processes/$Process”
      append site_path “/$subdir/”

      # set the user data… for the message
      set filename “TUFTS_MDPH_ELR_tmp”
      set filenameextension “txt”
      set fullname $site_path$filename.$filenameextension

      # open tmp file, write record
      set curFileID [open $fullname a]
      #################  puts -nonewline $curFileID $msg\r
      puts -nonewline $curFileID $msg

      # close tmp File
      close $curFileID

      # return message
      # Always KILL original
      # KILL may not work in UPOC write in Cloverleaf v5.3
      # Get “Unsupported Disposition” Error and msgs in Error DB
      # Use CONTINUE for now, may check KILL when upgrade to Cloverleaf v5.6. complete
      set dispList

        }

        time {
        # Timer-based processing
        # N.B.: there may or may not be a MSGID key in args

        # Build envelope
        set cloverclock [clock format [clock second] -format %Y%m%d%H%M%S]

        # Original batch header formatting
        # set fhs “FHS|^~\\&|Softlab|TUFTS|ELR|MDPH|$cloverclock||$cloverclock|||\r”
        # set bhs “BHS|^~\\&|Softlab|TUFTS|ELR|MDPH|$cloverclock||$cloverclock|||\r”

        # New batch header formatting
        set fhs “FHS|^~\\&#|SCC|TUFTS^22D0074723^CLIA|RR1MSH5|MLAB^22D0074723^CLIA|$cloverclock||$cloverclock|||\r”
        set bhs “BHS|^~\\&|LAB|TUFTS^22D0074723^CLIA|RR1MSH5|MLAB^22D0074723^CLIA|$cloverclock||$cloverclock|||\r”
        ## set fhs “FHS|^~\\&|SOFTLAB^2.16.840.1.113883.3.3013.77.1^ISO|TUFTS^22D0074723^CLIA|RR1MSH5|MLAB^22D0074723^CLIA|$cloverclock||$cloverclock|||\r”
        ## set bhs “BHS|^~\\&|SOFTLAB^2.16.840.1.113883.3.3013.77.1^ISO|TUFTS^22D0074723^CLIA|RR1MSH5|MLAB^22D0074723^CLIA|$cloverclock||$cloverclock|||\r”

        # Sample from MDPH
        # MSH|^~\&|Sample Lab System^2.16.840.1.113883.19.3.1^ISO|SampleHospital^22D0076229^CLIA|MA-MDPH^2.16.840.1.113883.19.3.2^ISO
        #|MA-MDPH^2.16.840.1.113883.19.3.2^ISO|20130101123558-0400||ORU^R01^ORU_R01|SH20130101123558|P|2.5.1|||AL|AL
        #|||||PHLabReport-Ack^^2.16.840.1.113883.9.11^ISO

        # Sample within Softlab record — 11/5/2014
        # MSH|^~\&|SOFTLAB^2.16.840.1.113883.3.3013.77.1^ISO|TUFTS^22D0074723^CLIA|RR1MSH5|MLAB^22D0074723^CLIA|20141103095309-0500||ORU^R01^ORU_R01|570009460-2014110309|P|2.5.1|||AL|NE

        # set file header
        ### set fileheader $fhs\r\n$bhs\r
        set fileheader $fhs$bhs

        # set directory path
        set root_path [exec env HCIROOT]
        set site_path [exec env HCISITEDIR]
        set subdir “exec/processes/$Process”
        append site_path “/$subdir/”

        #Get the time in system seconds
        set systemTime [clock seconds]
        #Set the time using the hour, minute and second descriptors.
        set CurDate [clock format $systemTime -format {%Y%m%d}]
        set CurDateTime [clock format $systemTime -format {%Y%m%d%H%M}]

        # input file parameters
        # set the user data… for the message
        set filein “TUFTS_MDPH_ELR_tmp”
        set fileInExt “txt”
        set fullnameIn $site_path$filein.$fileInExt

        # set output path and filename
        # NOTE: “mdph_to_send” defined as Outpath, from beginning of proc
        set sub_path_out $Outpath
        append site_path $sub_path_out
        set fileout “TUFTS_MDPH_ELR_OUT”
        set fileoutExt  $CurDateTime

        set outFile $site_path$fileout.$fileoutExt

        # get input
        set tempfileFlagIn [file exists $fullnameIn]
        if {$tempfileFlagIn == 1} {
        set outFileID [open $outFile a+]
        # write header
        puts -nonewline $outFileID $fileheader
        #echo fileheader being written = $fileheader \n
        set inFileID [open $fullnameIn r]
        set wholefile1 [read $inFileID]

        #
        # split the file into its transactions
        # remove any blank transactions (extra newlines)

        set BatchTrnxCount 0
        foreach BatchRec [split $wholefile1 “\n”] {
        if {[clength $BatchRec] == 0} {
        continue
        } else {
        puts -nonewline $outFileID $BatchRec
        #echo batchrec = $BatchRec \n
        set BatchTrnxCount [regexp -all {MSH} $BatchRec]
        }
        }

        # set file TRAILER
        set bts “BTS|$BatchTrnxCount|\r”
        ###echo bts = $bts \n
        set fts “FTS|1|\r”
        ###echo fts = $fts \n
        set filetrailer $bts$fts
        #echo filetrailer = $filetrailer \n

        ### Write TRAILER

        set EOFcurr [eof $inFileID]
        if {$EOFcurr == 1} {
        puts -nonewline $outFileID $filetrailer
        close $outFileID
        }
        ### move code to inside if loop?
        ###close $outFileID

        close $inFileID

        # delete tmp Input file
        file delete $fullnameIn

        }

        }

        }

        return $dispList
        }

         

         

      1. #117751
        Bill Pitts
        Participant

        Update: We got this working; thanks to Tom Patton (Tufts integration) for his tcl expertise and fix.

        We split the output files from the tmp input file based upon record max counts.

        Kept the same UPoC and Advanced Scheduler setup

        Cron calls ftp script to send output files to server that stores java tunneling utility to State DPH.

        Powershell script created on that server to send all output files to State, await responses, and send email notification back to internal hospital team

        Modified (new) tclproc to split source tmp batch into multiple output files below:

         

        ######################################################################
        # Name:    tpsSoftlab_MDPHsplitBatch
        # Purpose:     Batch Header & Trailer and Output File for Softlab Results to MDPH ELR
        #              Need to split file into multiple files to avoid MDPH 1.5Mb max size limit
        #
        # Copied from tpsMDPHbatchAuto.tcl, which is used for Cerner ELR Results
        #
        #
        # UPoC type:    tps
        # Args:     tps keyedlist containing the following keys:
        #           MODE    run mode (“start”, “run” or “time”)
        #           MSGID   message handle
        #           ARGS    user-supplied arguments:
        #                   <describe user-supplied args here>
        #
        # Returns: tps disposition list:
        #          <describe dispositions used here>
        #
        #
        #
        #    *********************************************************************
        #    on RUN mode:    Appends msgs to temp file TUFTS_MDPH_ELR_tmp_in.txt
        #
        #                    Make sure to set Process name to “softlab” for TEST/PROD
        #
        #    on TIMER mode:  Writes header, reads/write msgs from temp file to
        #                    TUFTS_MDPH_ELR_OUT.yyyymmddhhmm file, writes trailer
        #
        #                    Modified to create multiple files if suspected of approaching
        #                    MDPH max file size limit of 1.5Mb
        #
        #                    Deletes .tmp file upon completion
        #
        #    ***********************************************************************
        #
        #———————————————————————————–
        # Modifications:
        #
        #  date   init     mod desc
        #  7/9/2020 whp   Need to split file into multiple files to avoid MDPH 1.5Mb max size limit
        #                 File sizes increased since Covid-19 reporting, approx early April 2020
        #  8/3/2020 tgp   adjusted this script to embedd a file# in the file name
        #
        #———————————————————————————–

        proc tpsSoftlab_MDPHsplitBatch { args } {

        keylget args MODE mode              ;# Fetch mod

        set dispList {}                ;# Nothing to return

        #Make sure to set Process name to “softlab” for TEST/PROD
        set Process “softlab”
        #set Process “testing”
        set Outpath “/mdph_to_send/”

        # variables needed to determine and split large files
        set filelargeFlag “N”
        set multiFileFlag “N”
        set fileNum {1}
        set filesizeMax {700000}
        set recCountMax {199} ; # keep 1 less than the actual count wanted
        set numFiles {0}
        set OutFilesSize {0}

        switch -exact — $mode {
        start {
        # startup stuff
        # N.B.: there may or may not be a MSGID key in args
        }

        run {
        # ‘run’ mode always has a MSGID; fetch and process it
        keylget args MSGID mh
        set msg [msgget $mh]

        # Get rid of all \x1c and \x0b
        regsub -all — {[\x1c\x0b]} $msg {} msg

        #Get the time in system seconds
        set systemTime [clock seconds]
        #Set the time using the hour, minute and second descriptors.
        set CurDate [clock format $systemTime -format {%Y%m%d}]
        set CurDateTime [clock format $systemTime -format {%Y%m%d%H%M}]

        # set directory path
        set root_path [exec env HCIROOT]
        set site_path [exec env HCISITEDIR]
        set subdir “exec/processes/$Process”
        append site_path “/$subdir/”

        # set the user data… for the message
        set filename “TUFTS_MDPH_ELR_tmp”
        set filenameextension “txt”
        set fullname $site_path$filename.$filenameextension

        # open  the tmp file, write record
        set curFileID [open $fullname a]
        ##fconfigure $curFileID -translation lf
        ## puts -nonewline $curFileID $msg\r

        ####puts -nonewline $curFileID $msg
        puts $curFileID $msg

        # close the tmp File
        close $curFileID

        # return message
        # Always KILL original
        # KILL may not work in UPOC write in Cloverleaf v5.3
        # Get “Unsupported Disposition” Error and msgs in Error DB
        # Use CONTINUE for now, may check KILL when upgrade to Cloverleaf v5.6. complete
        set dispList

          }

          time {
          # Timer-based processing
          # N.B.: there may or may not be a MSGID key in args

          # Build envelope
          set cloverclock [clock format [clock second] -format %Y%m%d%H%M%S]

          # New batch header formatting
          set fhs “FHS|^~\\&#|SCC|TUFTS^22D0074723^CLIA|RR1MSH5|MLAB^22D0074723^CLIA|$cloverclock||$cloverclock|||\r”
          set bhs “BHS|^~\\&|LAB|TUFTS^22D0074723^CLIA|RR1MSH5|MLAB^22D0074723^CLIA|$cloverclock||$cloverclock|||\r”

          # Sample from MDPH
          # MSH|^~\&|Sample Lab System^2.16.840.1.113883.19.3.1^ISO|SampleHospital^22D0076229^CLIA|MA-MDPH^2.16.840.1.113883.19.3.2^ISO
          #|MA-MDPH^2.16.840.1.113883.19.3.2^ISO|20130101123558-0400||ORU^R01^ORU_R01|SH20130101123558|P|2.5.1|||AL|AL
          #|||||PHLabReport-Ack^^2.16.840.1.113883.9.11^ISO

          # Sample within Softlab record — 11/5/2014
          # MSH|^~\&|SOFTLAB^2.16.840.1.113883.3.3013.77.1^ISO|TUFTS^22D0074723^CLIA|RR1MSH5|MLAB^22D0074723^CLIA|20141103095309-0500||ORU^R01^ORU_R01|570009460-2014110309|P|2.5.1|||AL|NE

          # set file header
          ### set fileheader $fhs\r\n$bhs\r
          set fileheader $fhs$bhs

          # set directory path
          set root_path [exec env HCIROOT]
          set site_path [exec env HCISITEDIR]
          set subdir “exec/processes/$Process”
          append site_path “/$subdir/”

          #Get the time in system seconds
          set systemTime [clock seconds]
          #Set the time using the hour, minute and second descriptors.
          set CurDate [clock format $systemTime -format {%Y%m%d}]
          set CurDateTime [clock format $systemTime -format {%Y%m%d%H%M}]

          # input file parameters
          # set the user data… for the message
          set filein “TUFTS_MDPH_ELR_tmp”
          set fileInExt “txt”
          set fullnameIn $site_path$filein.$fileInExt

          # set output path and filename
          # NOTE: “mdph_to_send” defined as Outpath, from beginning of proc
          set sub_path_out $Outpath
          append site_path $sub_path_out
          set fileout “TUFTS_MDPH_ELR_OUT”
          set fileoutExt  $CurDateTime

          # get input
          set tempfileFlagIn [file exists $fullnameIn]

          if {$tempfileFlagIn == 1} {

          set outFile $site_path$fileout$fileNum.$fileoutExt
          set outFileID [open $outFile a+]

          # write header
          puts -nonewline $outFileID $fileheader

          # read date in from input file
          set inFileID [open $fullnameIn r]
          fconfigure $inFileID -buffering line

          set wholefile1 [read $inFileID]
          # split the file into its transactions
          # remove any blank transactions (extra newlines)

          set BatchTrnxCount 0
          set RecCount 0

          foreach BatchRec [split $wholefile1 “\n”] {
          if {[clength $BatchRec] == 0} {
          continue
          } else {
          # check file size before batchrec write
          set OutFileSize [file size $outFile]
          # create and write trailer, close outFileID –
          # start new file if over size limit
          if {$RecCount > $recCountMax} {
          set bts “BTS|$RecCount|\r”
          set fts “FTS|1|\r”
          set filetrailer $bts$fts
          puts -nonewline $outFileID $filetrailer
          close $outFileID

          # prep new file
          incr fileNum
          set outFile $site_path$fileout$fileNum.$fileoutExt
          set outFileID [open $outFile a+]
          set RecCount 0

          # write header for new file
          puts -nonewline $outFileID $fileheader
          }
          #  write out batch record – then check if over sized and wrap up file and start new
          puts -nonewline $outFileID $BatchRec
          incr RecCount
          }
          }

          # set file TRAILER
          set bts “BTS|$RecCount|\r”
          set fts “FTS|1|\r”
          set filetrailer $bts$fts

          ### Write TRAILER
          set EOFcurr [eof $inFileID]
          if {$EOFcurr == 1} {
          puts -nonewline $outFileID $filetrailer
          close $outFileID
          }

          close $inFileID

          # delete tmp Input file
          file delete $fullnameIn
          } else {
          echo “No Lab ELR input file exists in process directory”
          }
          }

          }

          return $dispList
          }

      Viewing 2 reply threads
      • You must be logged in to reply to this topic.

      Forum Statistics

      Registered Users
      5,115
      Forums
      28
      Topics
      9,290
      Replies
      34,422
      Topic Tags
      286
      Empty Topic Tags
      10