Skip to content

Commit

Permalink
Merge pull request #2340 from AllenInstitute/bugfix/2340-make-url-req…
Browse files Browse the repository at this point in the history
…uest-fail-gracefully

Make URLRequest fail gracefully
  • Loading branch information
t-b authored Feb 10, 2025
2 parents 4b66f02 + b6acc0a commit 2e1ca7a
Show file tree
Hide file tree
Showing 7 changed files with 96 additions and 31 deletions.
1 change: 1 addition & 0 deletions Packages/MIES/MIES_Constants.ipf
Original file line number Diff line number Diff line change
Expand Up @@ -1671,6 +1671,7 @@ Constant POST_PLOT_FULL_UPDATE = 0x8 ///< Forces a complete update from scra
///@{
StrConstant WORKLOADCLASS_TP = "TestPulse"
StrConstant WORKLOADCLASS_NWB = "nwb_writing"
StrConstant WORKLOADCLASS_URL = "json_payload_upload"
///@}

/// @name Column numbers of epoch information
Expand Down
2 changes: 2 additions & 0 deletions Packages/MIES/MIES_IgorHooks.ipf
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,8 @@ static Function IH_Cleanup()

DFREF dfrNWB = GetNWBFolder()
KilLVariables/Z dfrNWB:histRefNumber

ASSERT(!ASYNC_WaitForWLCToFinishAndRemove(WORKLOADCLASS_URL, 300), "JSON Payload upload did not finish within timeout of 300s.")
catch
ClearRTError()
BUG("Caught runtime error or assertion: " + num2istr(err))
Expand Down
32 changes: 9 additions & 23 deletions Packages/MIES/MIES_MiesUtilities_Uploads.ipf
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,7 @@ Function UploadCrashDumpsDaily()
return NaN
endif

if(UploadCrashDumps())
printf "Crash dumps have been successfully uploaded.\r"
endif
UploadCrashDumps()

JSON_SetString(jsonID, "/diagnostics/last upload", GetIso8601TimeStamp())
AbortOnRTE
Expand Down Expand Up @@ -142,13 +140,7 @@ static Function UploadPing()

jsonID = GenerateJSONTemplateForUpload()
AddPayloadEntries(jsonID, {UPLOAD_BLOCK_USERPING}, {payload}, isBinary = 0)
AssertOnAndClearRTError()
try
UploadJSONPayload(jsonID); AbortOnRTE
catch
err = ClearRTError()
endtry
JSON_Release(jsonID)
UploadJSONPayloadAsync(jsonID)

return err
End
Expand Down Expand Up @@ -181,8 +173,6 @@ End
/// The uploaded files are moved out of the way afterwards.
///
/// See `tools/http-upload/upload-json-payload-v1.php` for the JSON format description.
///
/// @return 1 if crash dumps had been uploaded, 0 otherwise
Function UploadCrashDumps()

string diagSymbPath, basePath, diagPath
Expand All @@ -198,12 +188,9 @@ Function UploadCrashDumps()
numLogs = DimSize(logs, ROWS)

if(!numFiles && !numLogs)
return 0
return NaN
endif

printf "Please wait while we upload %d crash dumps. This might take a while.\r", numFiles + numLogs
ControlWindowToFront()

jsonID = GenerateJSONTemplateForUpload()

AddPayloadEntriesFromFiles(jsonID, files, isBinary = 1)
Expand All @@ -219,16 +206,16 @@ Function UploadCrashDumps()
SaveTextFile(JSON_dump(jsonID, indent = 4), diagPath + ":" + UniqueFileOrFolder(basePath, "crash-dumps", suffix = ".json"))
#endif // DEBUGGING_ENABLED

UploadJSONPayload(jsonID)
JSON_Release(jsonID)
UploadJSONPayloadAsync(jsonID)

#ifndef DEBUGGING_ENABLED
MoveFolder/P=$basePath "Diagnostics" as UniqueFileOrFolder(basePath, "Diagnostics_old")
#endif // DEBUGGING_ENABLED

DEBUGPRINT_ELAPSED(referenceTime)

return 1
printf "Uploading %d crash dumps is in progress in the background.\r", numFiles + numLogs
ControlWindowToFront()
End

/// @brief Upload the MIES and ZeroMQ logfiles
Expand Down Expand Up @@ -341,15 +328,14 @@ Function UploadLogFiles([variable verbose, variable firstDate, variable lastDate
sprintf out, "Uploading %.0f MB (~%d Bytes)", sumSize / MEGABYTE, sumSize
UploadLogFilesPrint(out, verbose)
for(jsonID : jsonIDs)
UploadJSONPayload(jsonID)
JSON_Release(jsonID)
UploadJSONPayloadAsync(jsonID)

UploadLogFilesPrint(".", verbose)
endfor
UploadLogFilesPrint("\r", verbose)
endif
UploadLogFilesPrint("Done.\r", verbose)

sprintf out, "Successfully uploaded the MIES, ZeroMQ-XOP and ITCXOP2 logfiles. Please mention your ticket \"%s\" if you are contacting support.\r", ticket
sprintf out, "Uploading the MIES, ZeroMQ-XOP and ITCXOP2 logfiles is in progress in the background. Please mention your ticket \"%s\" if you are contacting support.\r", ticket
UploadLogFilesPrint(out, verbose)
End

Expand Down
56 changes: 52 additions & 4 deletions Packages/MIES/MIES_Utilities_System.ipf
Original file line number Diff line number Diff line change
Expand Up @@ -327,13 +327,61 @@ Function IsWindows10Or11()
return GrepString(os, "^(Microsoft )?Windows 1[01]? ")
End

/// @brief Upload the given JSON document
Function UploadJSONPayloadAsync(variable jsonID)

DFREF threadDFR = ASYNC_PrepareDF("UploadJSONPayloadAsyncWorker", "UploadJSONPayloadAsyncReadout", WORKLOADCLASS_URL, inOrder = 0)

ASYNC_AddParam(threadDFR, var = jsonID, name = "jsonID")

ASYNC_Execute(threadDFR)
End

threadsafe Function/DF UploadJSONPayloadAsyncWorker(DFREF threadDFR)

variable jsonID, ret

jsonID = ASYNC_FetchVariable(threadDFR, "jsonID")

ret = UploadJSONPayload(jsonID)

DFREF dfrOut = NewFreeDataFolder()
variable/G dfrOut:result = ret

return dfrOut
End

Function UploadJSONPayloadAsyncReadout(STRUCT ASYNC_ReadOutStruct &ar)

// nothing to do
End

/// @brief Upload the given JSON document and release it
///
/// See `tools/http-upload/upload-json-payload-v1.php` for the JSON format description.
Function UploadJSONPayload(variable jsonID)
threadsafe Function UploadJSONPayload(variable jsonID)

variable skip

#ifdef AUTOMATED_TESTING
WAVE/Z overrideResults = GetOverrideResults()
skip = WaveExists(overrideResults) ? overrideResults[0] : 0
#endif // AUTOMATED_TESTING

if(!skip)
URLRequest/Z=1/DSTR=(JSON_Dump(jsonID)) url="https://ai.customers.byte-physics.de/upload-json-payload-v1.php", method=put
else
V_flag = 1
S_ServerResponse = "fake error"
endif

JSON_Release(jsonID)

if(V_Flag)
LOG_AddEntry(PACKAGE_MIES, "URLRequest failed", keys = {"S_ServerResponse", "V_Flag"}, values = {S_ServerResponse, num2str(V_Flag)}, stacktrace = 1)
return 1
endif

URLrequest/DSTR=(JSON_Dump(jsonID)) url="https://ai.customers.byte-physics.de/upload-json-payload-v1.php", method=put
ASSERT(!V_Flag, "URLrequest did not succeed due to: " + S_ServerResponse)
return 0
End

/// @brief Returns a hex string which is unique for the given Igor Pro session
Expand Down
4 changes: 2 additions & 2 deletions Packages/MIES/MIES_WaveDataFolderGetters.ipf
Original file line number Diff line number Diff line change
Expand Up @@ -7591,9 +7591,9 @@ End
/// @brief Return the wave used for storing mock data for tests
///
/// This wave is created by MSQ_CreateOverrideResults(),
/// PSQ_CreateOverrideResults() or TP_CreateOverrideResults() and does also not
/// PSQ_CreateOverrideResults(), TP_CreateOverrideResults(), CreateOverrideResults() and does also not
/// follow our usual rules so it might not exist.
Function/WAVE GetOverrideResults()
threadsafe Function/WAVE GetOverrideResults()

DFREF dfr = root:
WAVE/Z/SDFR=dfr overrideResults
Expand Down
23 changes: 22 additions & 1 deletion Packages/tests/Basic/UTF_Utils_System.ipf
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
// GetASLREnabledState
// TurnOffASLR
// IsWindows10
// UploadJSONPayload
// GetIgorInstanceID
// CleanupOperationQueueResult

Expand Down Expand Up @@ -89,3 +88,25 @@ static Function TestErrorCodeConversion()
End

/// @}

/// UploadJSONPayload
/// @{
static Function TestUploadJsonPayload()

variable jsonID
string filename, logs, retFilename

WAVE overrideResults = CreateOverrideResults(1)
overrideResults[] = 1

filename = LOG_GetFile(PACKAGE_MIES)
DeleteFile/Z filename

jsonID = JSON_New()
UploadJSONPayload(jsonID)

[logs, retFilename] = LoadTextFile(filename)
CHECK_PROPER_STR(logs)
CHECK(GrepString(logs, "\"S_ServerResponse\":\"fake error\",\"V_Flag\":\"1\",\"action\":\"URLRequest failed"))
End
/// @}
9 changes: 8 additions & 1 deletion Packages/tests/UTF_HelperFunctions.ipf
Original file line number Diff line number Diff line change
Expand Up @@ -1187,8 +1187,15 @@ End

Function ResetOverrideResults()

CreateOverrideResults(0)
End

Function/WAVE CreateOverrideResults(variable numRows)

KillOrMoveToTrash(wv = root:overrideResults)
Make/N=0 root:overrideResults
Make/N=(numRows) root:overrideResults/WAVE=wv

return wv
End

Function [string baseSet, string stimsetList, string customWavePath, variable amplitude] CreateDependentStimset()
Expand Down

0 comments on commit 2e1ca7a

Please sign in to comment.