1 #ifndef GET_BLOB_CALLBACK__HPP 2 #define GET_BLOB_CALLBACK__HPP 3 4 /* $Id: get_blob_callback.hpp 611588 2020-07-08 14:00:18Z satskyse $ 5 * =========================================================================== 6 * 7 * PUBLIC DOMAIN NOTICE 8 * National Center for Biotechnology Information 9 * 10 * This software/database is a "United States Government Work" under the 11 * terms of the United States Copyright Act. It was written as part of 12 * the author's official duties as a United States Government employee and 13 * thus cannot be copyrighted. This software/database is freely available 14 * to the public for use. The National Library of Medicine and the U.S. 15 * Government have not placed any restriction on its use or reproduction. 16 * 17 * Although all reasonable efforts have been taken to ensure the accuracy 18 * and reliability of the software and data, the NLM and the U.S. 19 * Government do not and cannot warrant the performance or results that 20 * may be obtained by using this software or data. The NLM and the U.S. 21 * Government disclaim all warranties, express or implied, including 22 * warranties of performance, merchantability or fitness for any particular 23 * purpose. 24 * 25 * Please cite the author in any work or product based on this material. 26 * 27 * =========================================================================== 28 * 29 * Authors: Sergey Satskiy 30 * 31 * File Description: 32 * 33 */ 34 35 #include "cass_fetch.hpp" 36 #include "pubseq_gateway.hpp" 37 #include "pubseq_gateway_convert_utils.hpp" 38 39 #include <functional> 40 41 using TBlobChunkCB = function<void(CCassBlobFetch * fetch_details, 42 CBlobRecord const & blob, 43 const unsigned char * chunk_data, 44 unsigned int data_size, 45 int chunk_no)>; 46 using TBlobPropsCB = function<void(CCassBlobFetch * fetch_details, 47 CBlobRecord const & blob, 48 bool is_found)>; 49 using TBlobErrorCB = function<void(CCassBlobFetch * fetch_details, 50 CRequestStatus::ECode status, 51 int code, 52 EDiagSev severity, 53 const string & message)>; 54 55 56 class CBlobChunkCallback 57 { 58 public: CBlobChunkCallback(TBlobChunkCB blob_chunk_cb,CCassBlobFetch * fetch_details)59 CBlobChunkCallback(TBlobChunkCB blob_chunk_cb, 60 CCassBlobFetch * fetch_details) : 61 m_BlobChunkCB(blob_chunk_cb), 62 m_FetchDetails(fetch_details), 63 m_BlobSize(0), 64 m_BlobRetrieveTiming(chrono::high_resolution_clock::now()) 65 {} 66 operator ()(CBlobRecord const & blob,const unsigned char * data,unsigned int size,int chunk_no)67 void operator()(CBlobRecord const & blob, const unsigned char * data, 68 unsigned int size, int chunk_no) 69 { 70 if (chunk_no >= 0) 71 m_BlobSize += size; 72 else 73 CPubseqGatewayApp::GetInstance()->GetTiming(). 74 Register(eBlobRetrieve, eOpStatusFound, 75 m_BlobRetrieveTiming, m_BlobSize); 76 77 m_BlobChunkCB(m_FetchDetails, blob, data, size, chunk_no); 78 } 79 80 private: 81 TBlobChunkCB m_BlobChunkCB; 82 CCassBlobFetch * m_FetchDetails; 83 84 unsigned long m_BlobSize; 85 chrono::high_resolution_clock::time_point m_BlobRetrieveTiming; 86 }; 87 88 89 class CBlobPropCallback 90 { 91 public: CBlobPropCallback(TBlobPropsCB blob_prop_cb,shared_ptr<CPSGS_Request> request,shared_ptr<CPSGS_Reply> reply,CCassBlobFetch * fetch_details,bool need_timing)92 CBlobPropCallback( 93 TBlobPropsCB blob_prop_cb, 94 shared_ptr<CPSGS_Request> request, 95 shared_ptr<CPSGS_Reply> reply, 96 CCassBlobFetch * fetch_details, 97 bool need_timing) : 98 m_BlobPropCB(blob_prop_cb), 99 m_Request(request), 100 m_Reply(reply), 101 m_FetchDetails(fetch_details), 102 m_InProcess(false), 103 m_NeedTiming(need_timing) 104 { 105 if (need_timing) 106 m_BlobPropTiming = chrono::high_resolution_clock::now(); 107 } 108 operator ()(CBlobRecord const & blob,bool is_found)109 void operator()(CBlobRecord const & blob, bool is_found) 110 { 111 if (!m_InProcess) { 112 if (m_Request->NeedTrace()) { 113 if (is_found) { 114 m_Reply->SendTrace("Cassandra blob props: " + 115 ToJson(blob).Repr(CJsonNode::fStandardJson), 116 m_Request->GetStartTimestamp()); 117 } else { 118 m_Reply->SendTrace("Cassandra blob props not found", 119 m_Request->GetStartTimestamp()); 120 } 121 } 122 123 if (m_NeedTiming) { 124 CPubseqGatewayApp * app = CPubseqGatewayApp::GetInstance(); 125 if (is_found) 126 app->GetTiming().Register(eLookupCassBlobProp, 127 eOpStatusFound, 128 m_BlobPropTiming); 129 else 130 app->GetTiming().Register(eLookupCassBlobProp, 131 eOpStatusNotFound, 132 m_BlobPropTiming); 133 } 134 135 m_InProcess = true; 136 m_BlobPropCB(m_FetchDetails, blob, is_found); 137 m_InProcess = false; 138 } 139 } 140 141 private: 142 TBlobPropsCB m_BlobPropCB; 143 shared_ptr<CPSGS_Request> m_Request; 144 shared_ptr<CPSGS_Reply> m_Reply; 145 CCassBlobFetch * m_FetchDetails; 146 147 // Avoid an infinite loop 148 bool m_InProcess; 149 150 // Timing 151 bool m_NeedTiming; 152 chrono::high_resolution_clock::time_point m_BlobPropTiming; 153 }; 154 155 156 class CGetBlobErrorCallback 157 { 158 public: CGetBlobErrorCallback(TBlobErrorCB blob_error_cb,CCassBlobFetch * fetch_details)159 CGetBlobErrorCallback(TBlobErrorCB blob_error_cb, 160 CCassBlobFetch * fetch_details) : 161 m_BlobErrorCB(blob_error_cb), 162 m_FetchDetails(fetch_details), 163 m_BlobRetrieveTiming(chrono::high_resolution_clock::now()) 164 {} 165 operator ()(CRequestStatus::ECode status,int code,EDiagSev severity,const string & message)166 void operator()(CRequestStatus::ECode status, 167 int code, 168 EDiagSev severity, 169 const string & message) 170 { 171 if (status == CRequestStatus::e404_NotFound) 172 CPubseqGatewayApp::GetInstance()->GetTiming(). 173 Register(eBlobRetrieve, eOpStatusNotFound, 174 m_BlobRetrieveTiming); 175 m_BlobErrorCB(m_FetchDetails, status, code, severity, message); 176 } 177 178 private: 179 TBlobErrorCB m_BlobErrorCB; 180 CCassBlobFetch * m_FetchDetails; 181 182 chrono::high_resolution_clock::time_point m_BlobRetrieveTiming; 183 }; 184 185 #endif 186 187