Last active
December 23, 2019 22:28
-
-
Save ni-ko-o-kin/1a991ae262c6fb8bf295f0561afd5e34 to your computer and use it in GitHub Desktop.
elm-node
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
port module Main exposing (main) | |
import Json.Decode as D exposing (Decoder, Value) | |
import Json.Encode as E | |
import Platform exposing (worker) | |
type Msg | |
= Run Value | |
main : Program () () Msg | |
main = | |
worker | |
{ init = always ( (), Cmd.none ) | |
, update = update | |
, subscriptions = always (Sub.batch [ run Run ]) | |
} | |
type alias RunId = | |
String | |
type Input | |
= F1Input RunId (List Int) | |
| F2Input RunId String | |
type Output | |
= F1Output RunId Int | |
| F2Output RunId String | |
f1Decoder : Decoder Input | |
f1Decoder = | |
D.map2 F1Input | |
(D.field "runId" D.string) | |
(D.field "input" (D.list D.int)) | |
f2Decoder : Decoder Input | |
f2Decoder = | |
D.map2 F2Input | |
(D.field "runId" D.string) | |
(D.field "input" D.string) | |
functionSelector : String -> Decoder Input | |
functionSelector function = | |
case function of | |
"f1" -> | |
f1Decoder | |
"f2" -> | |
f2Decoder | |
_ -> | |
D.fail "function not supported" | |
decoder = | |
D.field "functionId" D.string | |
|> D.andThen functionSelector | |
f1Encoder : Int -> ( String, E.Value ) | |
f1Encoder result = | |
( "result", E.int result ) | |
f2Encoder : String -> ( String, E.Value ) | |
f2Encoder result = | |
( "result", E.string result ) | |
outputEncoder : Output -> E.Value | |
outputEncoder out = | |
let | |
go runId result encoder = | |
E.object | |
[ ( "status", E.string "ok" ) | |
, ( "runId", E.string runId ) | |
, encoder result | |
] | |
in | |
case out of | |
F1Output runId result -> | |
go runId result f1Encoder | |
F2Output runId result -> | |
go runId result f2Encoder | |
f1 : List Int -> Int | |
f1 = | |
List.length | |
f2 : String -> String | |
f2 = | |
String.reverse | |
inputToOutput : Input -> Output | |
inputToOutput input = | |
case input of | |
F1Input runId items -> | |
items | |
|> f1 | |
|> F1Output runId | |
F2Input runId text -> | |
text | |
|> f2 | |
|> F2Output runId | |
update : Msg -> () -> ( (), Cmd Msg ) | |
update (Run value) _ = | |
case D.decodeValue decoder value of | |
Err _ -> | |
( (), output Nothing ) | |
Ok input -> | |
( () | |
, input | |
|> inputToOutput | |
|> outputEncoder | |
|> Just | |
|> output | |
) | |
port run : (Value -> msg) -> Sub msg | |
port output : Maybe E.Value -> Cmd msg |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const { randomBytes } = require("crypto"); | |
const { Elm } = require("./elm-main"); | |
const App = Elm.Main.init({}); | |
const exec = async (functionId, outputCallback, runCallback, input) => { | |
const runId = randomBytes(16).toString("hex"); | |
const p = new Promise((resolve, reject) => { | |
let timeout; | |
const go = v => { | |
if (v && v.runId === runId) { | |
clearTimeout(timeout); | |
outputCallback.unsubscribe(go); | |
if (v.status === "ok") { | |
console.log( | |
[ | |
`resolved runId: ${runId}`, | |
` with input: ${input}`, | |
` to output: ${v.result}`, | |
"" | |
].join("\n") | |
); | |
resolve(v.result); | |
} else if (v.status === "error") { | |
console.log( | |
[ | |
`rejected runId: ${runId}`, | |
` with input: ${input}`, | |
` to msg: ${v.msg}`, | |
"" | |
].join("\n") | |
); | |
reject(v.msg); | |
} else { | |
reject("error: invalid response status"); | |
} | |
} | |
}; | |
outputCallback.subscribe(go); | |
timeout = setTimeout(() => { | |
outputCallback.unsubscribe(go); | |
reject("error: invalid input or time limit exceeded"); | |
}, 30 * 1000); | |
}); | |
setTimeout(() => { | |
runCallback.send({ runId, functionId, input }); | |
}, Math.random() * 1000); | |
return p; | |
}; | |
(async () => { | |
const f1s = new Array(10).fill(null).map((_, idx) => { | |
return exec("f1", App.ports.output, App.ports.run, new Array(idx).fill(1)); | |
}); | |
const f2s = new Array(14).fill(null).map((_, idx, ary) => { | |
return exec( | |
"f2", | |
App.ports.output, | |
App.ports.run, | |
"emosewa si mle".slice(idx) | |
); | |
}); | |
try { | |
console.log(await Promise.all([...f1s, ...f2s])); | |
} catch (e) { | |
console.error(e); | |
} | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment