139 {
140
141 std::string outputConnection = outputConnectionSpec.substr(0, outputConnectionSpec.find('['));
145 if (!this->
cleanUp(outputConnection).isSuccess()) {
147 return(StatusCode::FAILURE);
148 }
149 return(StatusCode::SUCCESS);
150 }
152 ATH_MSG_DEBUG(
"commitOutput SKIPPED for uninitialized server.");
153 return(StatusCode::SUCCESS);
154 }
155 std::map<void*, RootType> commitCache;
158
159 const char* placementStr = nullptr;
162 if (
sc.isSuccess() && placementStr !=
nullptr && strlen(placementStr) > 6 && num > 0) {
163 const char * matchedChars = strstr(placementStr, "[FILE=");
164 if (!matchedChars){
165 ATH_MSG_ERROR(std::format(
"No matching filename in {}", placementStr));
167 }
171 ATH_MSG_ERROR(std::format(
"Failed to connectOutput for {}", fileName));
173 }
175 bool dataHeaderSeen = false;
176 std::string dataHeaderID;
177 while (num > 0) {
178 std::string objName = "ALL";
179 if (useDetailChronoStat()) {
180 objName = placementStr;
181 }
182
183 {
184 PMonUtils::BasicStopWatch stopWatch("cRep_" + objName, this->m_chronoMap);
185 std::string_view pStr = placementStr;
186 std::string::size_type cpos = pStr.find ("[CONT=");
187 if (cpos == std::string::npos) {
188 ATH_MSG_ERROR(std::format(
"No CONT field in placement string: {}", pStr));
189 return StatusCode::FAILURE;
190 }
191 std::string tokenStr (pStr.substr(0, cpos));
192 std::string contName (pStr.substr(cpos, std::string::npos));
193 std::string::size_type cl1 = contName.find(']');
194 if (cl1 == std::string::npos) {
195 ATH_MSG_ERROR(std::format(
"Missing close bracket after CONT field in placement string: {}", pStr));
196 return StatusCode::FAILURE;
197 }
198 tokenStr.append(contName, cl1 + 1);
199 contName = contName.substr(6, cl1 - 6);
200
201 std::string::size_type ppos = pStr.find ("[PNAME=");
202 if (ppos == std::string::npos) {
203 ATH_MSG_ERROR(std::format(
"No PNAME field in placement string: {}", pStr));
204 return StatusCode::FAILURE;
205 }
206 std::string className (pStr.substr(ppos, std::string::npos));
207 std::string::size_type cl2 = className.find(']');
208 if (cl2 == std::string::npos) {
209 ATH_MSG_ERROR(std::format(
"Missing close bracket after PNAME field in placement string: {}", pStr));
210 return StatusCode::FAILURE;
211 }
212 className = className.substr(7, cl2 - 7);
215 const std::string numStr = std::to_string(num);
217 bool foundContainer = false;
218 std::size_t opPos = contName.find('(');
220 foundContainer = true;
221 } else {
223 if (contName.compare(0, opPos, item) == 0){
224 foundContainer = true;
225 len = item.size();
226 break;
227 }
228 }
229 }
230 if (len > 0 && foundContainer && contName[len] == '(' ) {
231 ServiceHandle<IIncidentSvc> incSvc(
"IncidentSvc",
name());
232
237 memName, {}, memName,
238 "BeginInputMemFile", "EndInputMemFile");
239 }
241 }
242
243 ServiceHandle<IAthMetaDataSvc> metadataSvc(
"MetaDataSvc",
name());
245 sc = metadataSvc->shmProxy(std::format(
"{}[NUM={}]", pStr, numStr));
246 if (
sc.isRecoverable()) {
248 }
else if (
sc.isFailure()) {
251 }
252 } else {
253 Token readToken;
254 readToken.
setOid(Token::OID_t(num, 0));
258
259 if( m_oneDataHeaderForm.value() ) {
260 auto placementWithSwn = [&] { return std::format("{}[SWN={}]", placementStr, num); };
261 if( className == "DataHeaderForm_p6" ) {
262
264 "", placementWithSwn());
265 DHcnv->updateRepRefs(&address, static_cast<DataObject*>(obj)).ignore();
266 tokenStr = "";
267 } else {
268 Placement placement;
271 if (token == nullptr) {
274 }
275 tokenStr = token->toString();
276 }
277 if( className == "DataHeader_p6" ) {
278
280 tokenStr, placementWithSwn());
281 if (!DHcnv->updateRep(&address, static_cast<DataObject*>(obj)).isSuccess()) {
284 }
285 } else
286 if (className !=
"Token" && className !=
"DataHeaderForm_p6" && !classDesc.
IsFundamental()) {
287 commitCache.insert(std::pair<void*, RootType>(obj, classDesc));
288 }
289 placementStr = nullptr;
290 } else {
291
292 Placement placement;
293 placement.
fromString(placementStr); placementStr =
nullptr;
295 if (token == nullptr) {
298 }
299 tokenStr = token->toString();
300 if (className == "DataHeader_p6") {
301
304
305 if (!DHcnv->updateRep(&address, static_cast<DataObject*>(obj)).isSuccess()) {
308 }
309 dataHeaderSeen = true;
310
311
312
313
314
315
316 dataHeaderID = std::format("{}/{}/{}", token->contID(), numStr, token->dbID().toString());
317 } else if (dataHeaderSeen) {
318 dataHeaderSeen = false;
319
320
321 if (className == "DataHeaderForm_p6") {
322
324 tokenStr, dataHeaderID);
325 if (!DHcnv->updateRepRefs(&address, static_cast<DataObject*>(obj)).isSuccess()) {
326 ATH_MSG_ERROR(
"Failed updateRepRefs for obj = " << tokenStr);
328 }
329 } else {
330
331 GenericAddress address(0, 0, "", dataHeaderID);
332 if (!DHcnv->updateRepRefs(&address, nullptr).isSuccess()) {
335 }
336 }
337 }
338 if (className !=
"Token" && className !=
"DataHeaderForm_p6" && !classDesc.
IsFundamental()) {
339 commitCache.insert(std::pair<void*, RootType>(obj, classDesc));
340 }
341 }
342 }
343 }
344
346 while (
sc.isRecoverable()) {
348 }
349 if (!
sc.isSuccess()) {
352 }
353 }
355 while (
sc.isRecoverable()) {
357 }
358 if (
sc.isFailure()) {
359
361 }
362 }
363 if (dataHeaderSeen) {
364
365 GenericAddress address(0, 0, "", std::move(dataHeaderID));
366 if (!DHcnv->updateRepRefs(&address, nullptr).isSuccess()) {
369 }
370 }
371 placementStr = nullptr;
372 }
else if (
sc.isSuccess() && placementStr !=
nullptr && strncmp(placementStr,
"stop", 4) == 0) {
373 return(StatusCode::RECOVERABLE);
374 }
else if (
sc.isRecoverable() || num == -1) {
375 return(StatusCode::RECOVERABLE);
376 }
378 ServiceHandle<IIncidentSvc> incSvc(
"IncidentSvc",
name());
380 {
382 memName, {}, memName,
383 "BeginInputMemFile", "EndInputMemFile");
384 }
385 if (
sc.isFailure()) {
386 ATH_MSG_INFO(
"All SharedWriter clients stopped - exiting");
387 } else {
389 }
390 return(StatusCode::FAILURE);
391 }
392 }
394 ATH_MSG_DEBUG(std::format(
"commitOutput SKIPPED for metadata-only server: {}", outputConnectionSpec));
395 return(StatusCode::SUCCESS);
396 }
397 if (outputConnection.empty()) {
398 outputConnection = std::move(fileName);
399 } else {
400 outputConnection = outputConnectionSpec;
403 }
404 }
405 std::size_t
merge = outputConnection.find(
"?pmerge=");
406 const std::string baseOutputConnection = outputConnection.substr(0, merge);
412 doCommit = true;
414 }
416 for (auto& [ptr, rootType] : commitCache) {
418 }
419 return(status);
420}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_DEBUG(x,...)
#define ATH_MSG_WARNING(x,...)
#define ATH_MSG_INFO(x,...)
#define ATH_MSG_FATAL(x,...)
bool merge(const StringPool &other)
Merge another pool into this one.
virtual StatusCode commitOutput(const std::string &outputConnectionSpec, bool doCommit) override
Implementation of IConversionSvc: Commit pending output.
std::map< std::string, int > m_fileCommitCounter
Force SharedWriter to flush data to output file at given intervals, needed by parallel compression.
Gaudi::Property< std::string > m_streamPortString
Extension to use ROOT TMemFile for event data, "?pmerge=<host>:<port>" for a TCP socket (default),...
virtual StatusCode cleanUp(const std::string &connection) override
Implement cleanUp to call all registered IAthenaPoolCleanUp cleanUp() function.
virtual void setObjPtr(void *&obj, const Token *token) override
bool m_streamServerActive
StatusCode abortSharedWrClients(int client_n)
Send abort to SharedWriter clients if the server quits on error.
Gaudi::Property< std::string > m_metadataContainerProp
For SharedWriter: To use MetadataSvc to merge data placed in a certain container.
virtual StatusCode connectOutput(const std::string &outputConnectionSpec, const std::string &openMode) override
Implementation of IConversionSvc: Connect to the output connection specification with open mode.
Gaudi::Property< std::vector< std::string > > m_metadataContainersAug
Gaudi::Property< bool > m_parallelCompression
Use Athena Object sharing for metadata only, event data is collected and send via ROOT TMemFile.
Gaudi::Property< std::map< std::string, int > > m_fileFlushSetting
virtual Token * registerForWrite(Placement *placement, const void *obj, const RootType &classDesc) override
const std::string & auxString() const
Access auxiliary string.
Placement & fromString(const std::string &from)
Build from the string representation of a placement.
static TScopeAdapter ByNameNoQuiet(const std::string &name, Bool_t load=kTRUE)
Bool_t IsFundamental() const
Token & setOid(const OID_t &oid)
Set object identifier.
Token & setAuxString(std::string &&auxString)
Set auxiliary string.
static const DbType POOL_StorageType
char rootType(char typeidType)
This function is used internally in the code when creating primitive dynamic auxiliary branches.
static constexpr CLID ID()