Multiple outbound threads to one Sqlite DB

Homepage Clovertech Forums Read Only Archives Cloverleaf Cloverleaf Multiple outbound threads to one Sqlite DB

  • Creator
    Topic
  • #55214
    Mike Strout
    Participant

    I have a need to send out GT1, IN1, and IN2 segments in outbound lab result messages, but our lab system, while it does take in these segments, will not send these segments out in results or charges.

    To deal with this, we grab these segments out of the various inbound message threads and throw them into a Sqlite DB. Then when the outbound message hits Cloverleaf, we pull the segments from the DB and lvarpop them back into the message with a Tcl script. This has worked pretty well for some time, but things are getting more complicated as we need to capture this info from more and more inbound feeds and push it to the same db.

    My question is, is it a problem to have several feeds passing messages to a single Sqlite DB? Also, we are about to switch pulling this data from the DB real-time as results go through the engine instead of pulling the data based on batch charges. Will I run into contention issues with several thousand writes to the DB across four threads and 2-400 reads per day from the DB from one thread?

    I don’t even know where to look other than Clovertech for design guidance on things like this.

Viewing 14 reply threads
  • Author
    Replies
    • #84577
      Jim Kosloskey
      Participant

      Mike,

      Here is a mail list for SqlLite Users: http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users

      Might be some assistance there.

      I would think you would need to also consider the I/O subsystem on your O/S. If it is already saturated or is about to be saturated, I don’t think it will matter much as to whether the DB will support that volume or not.

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

    • #84578
      David Coffey
      Participant

      You could create one thread specifically designed to instantiate data in the SQLite database,  All threads needing to store data in the SQLite database would route to it.   This would serialize the feed and (hopefully!) remove potential contention issues.

    • #84579
      Jeff Dinsmore
      Participant

      Mike,

      SQLite’s performance should be able to satisfy your needs.

      We have many SQLite databases that we’re writing thousands of records to per day.

      Our DBs are used in real-time interface applications that access these databases – some of them 300-400 MB in size – many thousands of times per day – all day, every day.  A few hundred reads per day should be trivial.

      You don’t say how you’re retrieving the info, but I’d guess you’re storing encounter number or something like that along with each of the stored segments.  Assuming so, make sure you create an index on your key lookup columns.  That will increase search performance dramatically.

      For databases that are accessed by multiple readers, I’ve recently started to use SQLite’s write ahead logging option (WAL) rather than the standard rollback journaling.  It handles concurrent access much better.  Below is a reference page discussing WAL.

      <a href="https://www.sqlite.org/wal.html&#8221; class=”bbcode_url”>https://www.sqlite.org/wal.html

      To solve any write concurrency issues, you might consider feeding all of the messages you need to write to the DB into a single multi-server thread that can then write them sequentially to the DB.

      Jeff Dinsmore
      Chesapeake Regional Healthcare

    • #84580
      Rob Lindsey
      Participant

      I was going to mention about the write vs read issue but I see others brought it up.  You can have multiple reads happening from the DB at one time but only a single write, unless you are using the -wal option.  The exclusive lock might cause you issues unless you program the timeout feature better than just waiting up to a certain amount of time.  This could cause a small delay in data messages going through your engine.

      I like the suggestion to feed the data to a singe thread that would write them into the sqlite db so that you dont have to deal with so many processes writing to the same DB at the same time.  I had to do something similar when I wrote a small sub-system to gather all of the stats for the data and try to shove them into sqlite db (one for each site running at the same time).  Huge write contention locks.  Had to write a service to accept the data and do the inserts in a serial fashion.

    • #84581
      Charlie Bursell
      Participant

      Can you put the thread that writes to the database and the one that reads in the same process?  That way there is no way you could be reading and writing at the same time

      With that said, as Jeff noted, there is no reason, even using concurrency locks that sqlite should not be able to keep up.

    • #84582
      Mike Strout
      Participant

      Thanks all for the great answers. I don’t know why I didn’t think about only having one write thread. I will definitely be implementing that soon. The WAL sounds interesting too, but may be overkill for this relatively low volume DB.

      Also, thanks Charlie about the same process idea. I do have a question about that though. We are on 6.1.2 and found that I will get a validation error if I have two db connections in the same process (not Tcl connections). I have another data flow that requires a long-term cache to pend result messages until the ordering provider is added to the order retrospectively (ER workflow). If the result doesn’t have a real ordering provider, I throw it into the DB kill the message. Then each day for three days I query the DB to get the message, CURL over to Epic to see if the ordering provider has been updated yet. If so, I update the message, send it on its way, and archive the record in the DB.

      Cloverleaf won’t let me have the OB Database Protocol and the IB Database Protocol in the same process. Anyone know why?

    • #84583
      Charlie Bursell
      Participant

      Perhaps a Tcl proc would be best for your application.  That is the way we did it prior to database protocol.

      I suppose the reason you can’t have the OB Database Protocol and the IB Database Protocol in the same process is possible contention problems.

      I am sure if you would ask Support they could get a more definitive answer fro Development.

    • #84584
      Jeff Dinsmore
      Participant

      Mike:

      Regardless of how low your volume is, I would recommend WAL.

      Even with just one reader and one writer – assuming they’re in different processes – you’ll have the opportunity for locking problems.  

      WAL completely eliminates that.  Writers do not block readers.

      You can configure WAL at DB creation or on existing DBs:

      Code:

      PRAGMA journal_mode=WAL

      I was surprised by how easy it was.  It takes two seconds to set and SQLite does the rest.

      Jeff Dinsmore
      Chesapeake Regional Healthcare

    • #84585
      Todd Horst
      Participant

      Old topic I know, but for this WAL do you execute it like:

      Code:

      db eval {PRAGMA journal_mode=WAL}

      Or is it in your table creation.

      In other words can you provide a more complete example?

    • #84586
      Jeff Dinsmore
      Participant

      For almost all datbases, I’ll set the WAL pragma at DB creation.

      But, you can certainly apply this change to an existing DB.

      Either way, it’s the same command – something like this:

      Code:

      set dbName xyz
      set dbFilePath /tmp/abcde

      if { [catch {sqlite3 $dbName $dbFilePath} dbErrs] } {
       # handle the error here
      } else {
       catch {$dbName eval “PRAGMA journal_mode=WAL”}
       catch {$dbName close}
      }

      Once set, it persists until reset to something else.

      Jeff Dinsmore
      Chesapeake Regional Healthcare

    • #84587
      Todd Horst
      Participant

      Yes, I see both your version and mine would work. Thanks.

      I found out that you can test what mode you are in via the following:

      Code:

      db eval {PRAGMA journal_mode} {
         echo $journal_mode
      }

      Read more here:

      http://www.sqlite.org/pragma.html#pragma_journal_mode

    • #84588
      Jeff Dinsmore
      Participant

      Your code won’t print journal mode in that form.

      You’ll need something like:

      Code:

      catch {db eval {PRAGMA journal_mode}} jm
      puts $jm

      or

      Code:

      set jm [db eval {PRAGMA journal_mode}]
      puts $jm

      Jeff Dinsmore
      Chesapeake Regional Healthcare

    • #84589
      Todd Horst
      Participant

      Mine and your two ALL work and return the same value of “WAL”, at least for me

    • #84590
      Jeff Dinsmore
      Participant

      You Are Correct Sir!  I stand corrected and educated.

      That’s an interesting and potentially useful function of SQLite’s eval method I’ve not used before.

      Jeff Dinsmore
      Chesapeake Regional Healthcare

    • #84591
      Todd Horst
      Participant

      its nice to say, loop over a result set, and create a list of dictionaries

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

Forum Statistics

Registered Users
5,117
Forums
28
Topics
9,292
Replies
34,435
Topic Tags
286
Empty Topic Tags
10