4
$\begingroup$

I want to launch an asynchronous task with Wolfram Script to listen to a socket and print back information in the CLI. This was handled in previous versions by ZeroMQLink``Private``$AsyncState["Task"] but this doesn't appear to work with my version (13, Win 11 x64).

Minimal Working Example:

#!/usr/bin/env wolframscript
(* ::Package:: *)
Quiet@DeleteObject[listener];

listener = SocketListen[
  3000,
  Function[{assoc},
   With[{client = assoc["SourceSocket"], data = assoc["Data"]},
    request = 
     ImportString[data, "HTTPRequest"]["Query"] /. {"name" -> n_} :> n;
    origin = Association[ request["Headers"] ]["origin"];
    If[ Head[origin] === Missing, origin = "" ];
response = ExportString[
  HTTPResponse[
   ExportString[<|"msg" -> "Hello, " <> ToString[request]|>, "JSON"],
    <|
    "StatusCode" -> 200,
    "ContentType" -> "application/json",
    "Headers" -> { "Access-Control-Allow-Origin" -> origin }
    |>], "HTTPResponse"];
    WriteString[client, response];
    Close[client];
    Print[DateString[] <> " - " <> "Request=" <> ToString[request]];
  ]
 ]
]

url = URLBuild[<|"Scheme" -> "http", 
"Domain" -> First[listener["Socket"]["DestinationIPAddress"]], 
"Port" -> listener["Socket"]["DestinationPort"]|>];

Print["Listening:  ", url, "\n"];

And to test in Powershell:

PS (Invoke-WebRequest -Method GET -Uri http://127.0.0.1:3000?name=kale).Content

Should return:

{
    "msg":"Hello, kale"
}

but exits out as soon as the script finishes executing.

How can I create this socket through WolframScript and keep it running until the script is closed using the new Background & Scheduled Tasks framework in Wolfram Language?

$\endgroup$
3
  • 1
    $\begingroup$ In version 13.0.1 there is ZeroMQLink`PackageScope`$AsyncState but it doesn't have the "Task" key, so even its "Status" key is incorrect because it needs "Task". Although there is ZeroMQLink`Loop`PackagePrivate`$backgroundTask which seems to be the right one, in my testing on your case, I couldn't respond to the client. $\endgroup$
    – Ben Izd
    Jun 2, 2022 at 6:48
  • $\begingroup$ @BenIzd It does appear to work with TaskWait, but yeah, clearly not responding to client. I snooped around quite a bit, but couldn't find that private package. How did you stumble on it? $\endgroup$
    – kale
    Jun 2, 2022 at 14:55
  • 1
    $\begingroup$ Names["ZeroMQLink*`*task*", IgnoreCase -> True] and also "ZeroMQLink*`*async*". It's interesting that even using First@AsynchronousTasks[] which I think should contain "Task" in previous versions, shows the same results (not responding). If you want to explore other possible solutions, you may take a look at Use function defined in Mathematica from Matlab (the Update section). I used a third-party ZeroMQ Java library. With some manipulation, you can build your own. $\endgroup$
    – Ben Izd
    Jun 2, 2022 at 15:27

1 Answer 1

2
$\begingroup$

How can I create this socket through WolframScript and keep it running until the script is closed [...]?

For the server I am using I have this and it seems to do its job well.

TaskWait[task = SessionSubmit[ScheduledTask["stayin'alive", 60]]]
$\endgroup$
2
  • $\begingroup$ Ah. After thinking about it today, I decided to go with TaskWait[SessionSubmit[While[True, Pause[60]]]] which is in a similar vein as yours. Not sure if there are any side effects of using Pause. $\endgroup$
    – kale
    Jun 4, 2022 at 4:05
  • $\begingroup$ Yup. Pause-while using no CPU time-does seem to gum up the evaluation queue. I'm accepting your answer. Much appreciated. $\endgroup$
    – kale
    Jun 4, 2022 at 4:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.