Writes errors not noted

  • Our server was restarted and for some random reason the mapped drive (a raid NAS) that we use for Conquest to store images did not get restored. Conquest happily kept reporting that studies were being written to the destination directory but in fact they weren't. This was verified by the existence of entries in the database that pointed to non-existent patient files. Nothing has been lost as we have several short term alternate storage mechanisms in place but still it doesn't inspire confidence.


    Is this a bug?

  • Hi,


    We solved that here long time ago already, making the following changes in dgate.cpp (the version we are using is 1.4.12alpha, maybe you have to change the code a bit for newer versions):


    1) At the beginning of the file


    Code
    # include <fstream>


    2) In method BOOL SaveToDisk() around line 3250:


    Code
    .... int t = time(NULL); if (!UseChapter10) PDU.SaveDICOMDataObject(Filename, ACRNEMA_VR_DUMP, DDOPtr); else if (bForcedImplicit) PDU.SaveDICOMDataObject(Filename, DICOM_CHAPTER_10_IMPLICIT, DDOPtr); else // OR (tested OK) chapter 10 format (does not compress) code in filepdu.cxx (dicom.lib) PDU.SaveDICOMDataObject(Filename, DICOM_CHAPTER_10_EXPLICIT, DDOPtr); // **** Alterations made by alsm ***** BOOL flag = FALSE; fstream fin; fin.open(Filename, ios::in); if( fin.is_open() ) { flag = TRUE; } fin.close(); if (!flag) { OperatorConsole.printf("***Error writing file: %s\n", Filename); return FALSE; } // ***** End alterations by alsm ***** SaveTime += time(NULL)-t; // OR (tested OK, no sequences) raw VR dump format (code in loadddo.cpp, this directory): // SaveDICOMDataObject (DDOPtr, Filename, FileCompressMode); // OR (tested OK, no sequences) Chapter 10 format (code in loadddo.cpp, this directory): // SaveDICOMDataObjectC10(DDOPtr, Filename, FileCompressMode);...


    3) Finally, use transactions in class MyUnknownStorage:


    Code
    ... // NOTE: NOT THREAD SAFE - IF ONE THREAD HANDLES READS AND WRITES THIS OPERATION CAN FAIL DUE TO DB SHARING: DB->SetAutoCommit(FALSE); // added by alsm if(!SaveToDisk(*DB, DDO, Filename, FALSE, ((AAssociateAC *)PDU)->CallingApTitle, ((AAssociateAC *)PDU)->CalledApTitle)) { DB->RollbackTrans(); // added by alsm DB->SetAutoCommit(TRUE); delete DDO; return StorageFailedErrorCode; // Processing failed } else { DB->CommitTrans(); // added by alsm DB->SetAutoCommit(TRUE);#ifdef DEBUG_MODE if(strlen(Filename)) OperatorConsole.printf("Written file: %s\n", Filename);#endif ImagesSaved++; return 0; } }...




    After modifying dgate.cpp, add the following code for transaction handling to file odbci.cpp:


    Code
    // ***** Added alsm for transaction handling *****BOOL Database :: SetAutoCommit (BOOL autocommit) {#ifdef WIN32 RetCode = SQLSetConnectAttr(hDbc, SQL_ATTR_AUTOCOMMIT, (SQLPOINTER)(autocommit ? SQL_AUTOCOMMIT_ON : SQL_AUTOCOMMIT_OFF), SQL_NTS); if (RetCode != SQL_SUCCESS) {#ifdef DB_DEBUG SystemDebug.printf("***Failed to SQLSetConnectAttr()\n");#endif return FALSE; }#endif return TRUE; }BOOL Database :: CommitTrans () {#ifdef WIN32 RetCode = SQLEndTran(SQL_HANDLE_DBC, hDbc, SQL_COMMIT); if (RetCode != SQL_SUCCESS) {#ifdef DB_DEBUG SystemDebug.printf("***Failed to SQLEndTran() (COMMIT)\n");#endif return FALSE; }#endif return TRUE; }BOOL Database :: RollbackTrans () {#ifdef WIN32 RetCode = SQLEndTran(SQL_HANDLE_DBC, hDbc, SQL_ROLLBACK); if (RetCode != SQL_SUCCESS) {#ifdef DB_DEBUG SystemDebug.printf("***Failed to SQLEndTran() (ROLLBACK)\n");#endif return FALSE; }#endif return TRUE; }// ***** End addition alsm for transaction handling *****



    and in odbci.hpp:



    Kind regards,


    Alberto A. Smulders
    Portugal

Participate now!

Don’t have an account yet? Register yourself now and be a part of our community!