› Clovertech Forums › Read Only Archives › Cloverleaf › Cloverleaf › How do I batch a thread?
We have a program that accepts real time ADT messaging for Cardiovascular Rehab. Our patients are recurring, and have new encounter numbers each month. The patients are registered into a pre-reg status halfway through the month, with that ADT message containing the new encounter number. The problem with passing those messages is that they will overwrite the encounter nunmber halfway through the month. The patients are only pushed with an admit status AFTER their first visit of the new month. I have no way to change the clinical workflow, so I am stuck needing to grab the pre-reg messages, queue them, then spit them out as a batch on the first of every month.
Is anyone out there currently doing this? What is the best way to perform this? My only solution would be to loop a tcl proc and reset a date variable on every loop, passing only if the month is greater than the month of the original message. This is not best practice, so I’d like to see if there is any better solution.
Thanks in advance.
Do you get the pre-reg data in an A05? When they have their first appt of the next month does that trigger an A01/A04? I don’t know your workflow, but is it possible you could skip sending the pre-reg to the cardio system altogether and let the other message do the job real-time?
I’m not able to visualize all aspects of your situation, but a thought does come to mind that could give you something to think about.
Right now I assume an integration like this at least
Inbound –> route all ADTs including the ADTs you want to que –> Outbound
so consider doing this
Inbound –> route all ADTs except the ones you want to que –> Outbound
|
–> route the ADTs you want to que –> que directory on cloverleaf
then pickup and send queued ADTs you’ve been holding when ready to process.
When I do this sort of thing I typically write num files, which means one file per message, to my que directory and then batch them up for sending when ready.
You could also append to a single file and process that when desirable.
either way you will then need an integration like this
load que file(s) –> route all queued ADTs –> outbound
Russ Ross
RussRoss318@gmail.com
Chris,
Yes we send the pre-reg A05, the problem being that those are the only messages prior to the patient’s first visit. The A04 comes only AFTER the patients first visit of the month. Therein lies the problem. I need those A05 messages to process, only at a later date.
Russ,
Your method is the method I am seeking to deploy. The problem is going to be in how I go about automating the queued messages outbound. I plan on building this into one encompassing tcl script:
1. Only pass A04, A05, and A08 messages. The receiving system has no concept of unique visits, so an A03 will only complicate things.
2. I will filter off the correct visit by comparing the PV1 admit date (YYYYMM) to the system date (YYYYMM). If they are equal, I will pass the message. If the admit date is than the system date, I will write it to a file and kill the message. (Did you suggest a .num extension, or is that just the term for YYYYMMDDHHMMSS_XX.txt? Also, ASCII or UTF? I’m assuming ASCII since it is what most of our threads run now.)
My problem is finding a way to automate those outbound messages on the first of each month. I do not want an open thread, as one of my co-workers could potentially start the thread by accident. I want the thread to only pass messages on the DD of 01. So should I set a Scheduled Task on the server that will start the filedrop thread on the 1st of each month, then also set up a script that verifies that it is indeed the first prior to processing the files? If you don’t mind, what is the command to start a thread?
Forgive me if I’m overlooking something obvious or overcomplicating the project, but I am still very new to this.
Thanks again,
Brandon.
I know what I described is at a high level because I’m too busy to do much more than that.
I suggest looking at my post on page 2 at this URL
<a href="https://usspvlclovertch2.infor.com/viewtopic.php?t=1907″ class=”bbcode_url”>https://usspvlclovertch2.infor.com/viewtopic.php?t=1907
To get some more detail and possibly adapt to your needs like including the date in the file name.
We do like you want and only start our batch integrations up and let them run until the batched up messages are done xlating.
This way the batch integration, which is in a separate site of their own are only turned on for maybe 1 – 10 minutes which most of the time is once a day but in your case probably once a month.
Since you asked, here are examples of commands to start and stop an interface
hcicmd -p p_odbc_caisis_adt -c “hs_odb_caisis_adt_32006 pstart”
hcicmd -p p_odbc_caisis_adt -c “hs_odb_caisis_adt_32006 pstop”
which I don’t use for my batch interfaces.
Instead I have every batch integration in their own site with autostart set for the interfaces and have an argument driven stand-alone TCL script ( _xlate_batch_file.tcl ) do all the work for me seen below that is taylored to my batch model so the rest is up to you to peel away if so desired:
#!/usr/bin/ksh
# this line to escape the next line from the tcl interpreter
exec hcitcl “$0” “$@”
# Begin Module Header ==============================================================================
#
#——
# Name:
#——
#
# _xlate_batch_file.tcl
#
#———
# Purpose:
#———
#
# Use the cloverleaf engine to xlate the messages in the batch file
#
#——–
# Inputs:
#——–
#
# process_name
#
#———
# Outputs:
#———
#
# none
#
#——-
# Notes:
#——-
#
# The monitor daemon (hcimonitord) does not have to be running to start and stop processes and interfaces.
# It only needs to run when someone wants to monitor the status of an interface with a gui like
# hcinetmonitor of a command line like hciconnstatus. Since the batch sites are not heavily monitored and
# run breifly behind the seens, it is desirable to leave the monitor daemon (hcimonitord) always turned off.
# Furthermore it is desirable to only turn on the lock manager while the interface is in use and turn it off
# once done.
#
# Normal Usage:
#
# _xlate_batch_file.tcl _003
#
#———
# History:
#———
#
# 2001.07.10 Russ Ross
# – wrote initial version (_xlate_batch_file.tcl).
#
# 2002.04.30 Russ Ross
# – wrote second version to accomodate separate batch sites
# by adding the following modifications:
#
# – stop the cloverleaf process in case is already running by mistake
# – be sure the lock manager is running before processing begins
# – be sure the monitor daemon is running efore processing begins
# – kill the lock manager after processing is done
# – be sure the monitor daemon is not running after processing is done
#
# 2002.05.06 Russ Ross
# – added an alert to email_hub_team every hour the clover process does not finish
#
# End Module Header ================================================================================
#—————
# initialization
#—————
set module_name “_xlate_batch_file.tcl”
set process_name [lindex $argv 0]
set thread_name_list “”
set load_thread_list “”
set dump_thread_list “”
#————————————————————–
# stop the cloverleaf process in case it is running by accident
#————————————————————–
if [file exists $HciSiteDir/exec/processes/$process_name] {
exec hcienginestop -p $process_name
}
#————————————————————-
# be sure the lock manager is running before processing begins
#————————————————————-
if ![file exists $HciSiteDir/exec/hcilockmgr/pid] {
exec hcisitectl -s l
}
#————————————————————–
# be sure the monitor daemon is running efore processing begins
#————————————————————–
if ![file exists $HciSiteDir/exec/hcimonitord/pid] {
exec hcisitectl -s m
}
#—————————–
# set the list of thread names
#—————————–
netcfgLoad
set thread_name_list [lsort [netcfgGetProcConns $process_name] ]
#—————————————-
# loop through each thread in the process
#—————————————-
foreach thread_name $thread_name_list {
#——————————————————
# zero out thread counts for each thread in the process
#——————————————————
exec hcimsiutil -zt $thread_name
#—————————————–
# set the symbolic link for the load files
#—————————————–
if [cequal [csubstr $thread_name 0 4] load] {
append load_thread_list $thread_name
system “rm -f $HciSiteDir/exec/processes/$process_name/$thread_name”
system “ln -sf /ftp/$env(MDA_BATCH_ENV)/iftp$process_name/work/$thread_name.pre-processed
$HciSiteDir/exec/processes/$process_name/$thread_name”
}
#——————————————
# set the symbolic links for the dump files
# and remove any spurious dump*.eof files
#——————————————
if [cequal [csubstr $thread_name 0 4] dump] {
append dump_thread_list $thread_name
system “rm -f $HciSiteDir/exec/processes/$process_name/$thread_name”
system “ln -sf /ftp/$env(MDA_BATCH_ENV)/oftp$process_name/work/$thread_name.xlated
$HciSiteDir/exec/processes/$process_name/$thread_name”
system “rm -f $HciSiteDir/exec/processes/$process_name/$thread_name.eof”
}
}
#—————————————–
# start the cloverleaf process that will
# xlate all the messages in the batch file
#—————————————–
exec hcienginerun -p $process_name
set minute_counter 0
#——————————————————–
# check every 60 seconds for all the eof files
# which act as a flag that the cloverleaf process is done
#——————————————————–
set process_not_done 1
while {$process_not_done} {
sleep 60
incr minute_counter 1
set process_not_done 0
foreach dump_thread $dump_thread_list {
if ![file exist $HciSiteDir/exec/processes/$process_name/$dump_thread.eof] { set process_not_done 1 }
}
if { [expr fmod($minute_counter,60) == 0] } {
set email_subject “site ($HciSite) process ($process_name) is still running after $minute_counter minutes”
system “echo “Subject: $email_subject\n.” | sendmail email_hub_team”
}
}
#——————————————————
# stop the cloverleaf process since
# it is done xlating all the messages in the batch file
#——————————————————
exec hcienginestop -p $process_name
#————————————————–
# remove any *.eof files from the process directory
#————————————————–
system “rm -f $HciSiteDir/exec/processes/$process_name/*.eof”
#————————————————————
# remove the input batch file since we are done processing it
#————————————————————
system “rm -f /ftp/$env(MDA_BATCH_ENV)/iftp$process_name/work/*.pre-processed”
#—————————————————————————–
# create a symbolic link to /dev/null for the load file
# defined in the NetConfig so it will not complain when saving new changes
#—————————————————————————–
foreach load_thread $load_thread_list {
system “ln -sf /dev/null $HciSiteDir/exec/processes/$process_name/$load_thread”
}
#—————————————————————————–
# create a symbolic link to /dev/null for the dump file
# defined in the NetConfig so it will not complain when saving new changes
#—————————————————————————–
foreach dump_thread $dump_thread_list {
system “ln -sf /dev/null $HciSiteDir/exec/processes/$process_name/$dump_thread”
}
#———————————————–
# kill the lock manager after processing is done
#———————————————–
if [file exists $HciSiteDir/exec/hcilockmgr/pid] {
exec hcisitectl -k l
}
#——————————————————————-
# be sure the monitor daemon is not running after processing is done
#——————————————————————-
if [file exists $HciSiteDir/exec/hcimonitord/pid] {
exec hcisitectl -k m
}
Russ Ross
RussRoss318@gmail.com
Here is an example of an ADT real-time numfiles to batch scheduled in cron to run once an hour that that ends up calling the _xlate_batch_file.tcl script show in my previous post as well as the other scripts involved for this entire batch integration, so you can see this is similar to what you have in mind.
[code]# #
Russ Ross
RussRoss318@gmail.com
I like the idea of having a site that opens each days, queues the recovery database, then shuts down after the database is empty, but I may have a more simplistic solution.
1. Create a directory and folder on the engine. Inside that folder would be a bunch of subfolders created by my original tcl script, titled by the date to process (for instance, 20130901).
2. Using a Scheduled Task, I create a tcl script that COPIES the contents of the folder with the system date to a folder named BATCH in the same directory. That way, each morning a copy will be created and I can maintain the message data in the orginial dated folder in case of emergency…
3. Then, I could simply point an inbound thread to a static location E:blablaTHREADNAMEBATCH. I was able to test this on my staging environment, and it works without having to restart the thread.
Sounds like your on your way to coming up with something to fit your situation.
Keep in mind that having a thread turned on that isn’t being used except once a month will reduce the available thread count if your cloverleaf license is restricted to a certain amount of running threads.
We have an unlimited thread count and I designed all our batch interfaces that are idle to be turned off because long ago I had resource constraints at the hardware level.
Now days the hardware is powerful enough this would go unoticed, but I just kept the design moving forward.
Russ Ross
RussRoss318@gmail.com
Brandon,
I know it’s been a while since you posted your question.
I use SQLite database to store messages that I am going to send later. We have to report particular Lab results to the Department of Public Health. The results should be sent once a day in a batch file (they provided their own transfer utility).
Some results are being sent on the same day when received from our HIS. Others may be sent a few days later or not sent at all – depending on the rules (for example, if there is a particular result send together all liver related results for this patient).
Either way a receiving thread analyses the messages and stores them in the SQLite database.
Another thread that runs on schedule (once a day, but can be any schedule) reads the database, creates a batch file with HL7 messages with whatever translation required and sends the batch.
Just another idea 🙂
Brandon,
I know it’s been a while since you posted your question.
I use SQLite database to store messages that I am going to send later. We have to report particular Lab results to the Department of Public Health. The results should be sent once a day in a batch file (they provided their own transfer utility).
Some results are being sent on the same day when received from our HIS. Others may be sent a few days later or not sent at all – depending on the rules (for example, if there is a particular result send together all liver related results for this patient).
Either way a receiving thread analyses the messages and stores them in the SQLite database.
Another thread that runs on schedule (once a day, but can be any schedule) reads the database, creates a batch file with HL7 messages with whatever translation required and sends the batch.
Just another idea 🙂