Skip to content

Commit

Permalink
Merge branch 'main' into swift-async-scenario-11
Browse files Browse the repository at this point in the history
  • Loading branch information
jamesward authored Dec 23, 2024
2 parents 8f8e763 + dab2975 commit 35e4eaf
Show file tree
Hide file tree
Showing 23 changed files with 279 additions and 32 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/clients.pkl
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ clients = new Mapping<String, Run> {
new {
run = """
echo Compiling Elm sources...
for num in {1..10}; do
for num in {1..11}; do
elm make --optimize --output=app/EasyRacer/Scenario$num.js src/EasyRacer/Scenario$num.elm
done
npm install --no-fund
Expand All @@ -31,7 +31,7 @@ clients = new Mapping<String, Run> {
}

["fsharp-reactive"] = new {
steps = GitHubAction.Dotnet.testSteps(null, "8.0.x", "./fsharp-reactive/EasyRacer.Tests")
steps = GitHubAction.Dotnet.testSteps(null, "9.0.x", "./fsharp-reactive/EasyRacer.Tests")
}

["go-conc"] = new {
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/elm-worker.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ jobs:
elm-version: 0.19.1
- run: |-
echo Compiling Elm sources...
for num in {1..10}; do
for num in {1..11}; do
elm make --optimize --output=app/EasyRacer/Scenario$num.js src/EasyRacer/Scenario$num.elm
done
npm install --no-fund
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/fsharp-reactive.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jobs:
- uses: actions/checkout@v4
- uses: actions/setup-dotnet@v4
with:
dotnet-version: 8.0.x
dotnet-version: 9.0.x
- run: dotnet test
working-directory: ./fsharp-reactive/EasyRacer.Tests
defaults:
Expand Down
18 changes: 9 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,27 +99,27 @@ docker run -it -p8080:8080 ghcr.io/jamesward/easyracer --debug
| [Scala 3 + ZIO](scala-zio) | 11/11 ![tests](https://github.com/jamesward/easyracer/actions/workflows/scala-zio.yaml/badge.svg) | [James Ward](https://github.com/jamesward) | |
| [Scala 3 + Ox](scala-ox) | 10/11 ![tests](https://github.com/jamesward/easyracer/actions/workflows/scala-ox.yaml/badge.svg) | [Adam Warski](https://github.com/adamw) | |
| [Scala 3 + Kyo](scala-kyo) | 10/11 ![tests](https://github.com/jamesward/easyracer/actions/workflows/scala-kyo.yaml/badge.svg) | [James Ward](https://github.com/jamesward) | |
| [Scala 3 + Gears](scala-gears) | 10/11 ![tests](https://github.com/jamesward/easyracer/actions/workflows/scala-gears.yaml/badge.svg) | [Jack Leow](https://github.com/jackgene) | |
| [Scala 3 + Akka Streams](scala-akkastreams) | 10/11 ![tests](https://github.com/jamesward/easyracer/actions/workflows/scala-akkastreams.yaml/badge.svg) | [Jack Leow](https://github.com/jackgene) | |
| [Kotlin + Coroutines](kotlin-coroutines) | 10/11 ![tests](https://github.com/jamesward/easyracer/actions/workflows/kotlin-coroutines.yaml/badge.svg) | [Jack Leow](https://github.com/jackgene) | |
| [Kotlin + Flow](kotlin-flow) | 10/11 ![tests](https://github.com/jamesward/easyracer/actions/workflows/kotlin-flow.yaml/badge.svg) | [Jack Leow](https://github.com/jackgene) | |
| [Scala 3 + Gears](scala-gears) | 11/11 ![tests](https://github.com/jamesward/easyracer/actions/workflows/scala-gears.yaml/badge.svg) | [Jack Leow](https://github.com/jackgene) | |
| [Scala 3 + Akka Streams](scala-akkastreams) | 11/11 ![tests](https://github.com/jamesward/easyracer/actions/workflows/scala-akkastreams.yaml/badge.svg) | [Jack Leow](https://github.com/jackgene) | |
| [Kotlin + Coroutines](kotlin-coroutines) | 11/11 ![tests](https://github.com/jamesward/easyracer/actions/workflows/kotlin-coroutines.yaml/badge.svg) | [Jack Leow](https://github.com/jackgene) | |
| [Kotlin + Flow](kotlin-flow) | 11/11 ![tests](https://github.com/jamesward/easyracer/actions/workflows/kotlin-flow.yaml/badge.svg) | [Jack Leow](https://github.com/jackgene) | |
| [Kotlin + Splitties](kotlin-splitties) | 11/11 ![tests](https://github.com/jamesward/easyracer/actions/workflows/kotlin-splitties.yaml/badge.svg) | [James Ward](https://github.com/jamesward) | |
| [Kotlin + Arrow](kotlin-arrow) | 11/11 ![tests](https://github.com/jamesward/easyracer/actions/workflows/kotlin-arrow.yaml/badge.svg) | [James Ward](https://github.com/jamesward) | |
| [Java + Loom](java-loom) | 10/11 ![tests](https://github.com/jamesward/easyracer/actions/workflows/java-loom.yaml/badge.svg) | [James Ward](https://github.com/jamesward) | |
| [Java + Jox](java-jox) | 11/11 ![tests](https://github.com/jamesward/easyracer/actions/workflows/java-jox.yaml/badge.svg) | [James Ward](https://github.com/jamesward) | |
| [Rust + Tokio](rust-tokio) | 10/11 ![tests](https://github.com/jamesward/easyracer/actions/workflows/rust-tokio.yaml/badge.svg) | [James Ward](https://github.com/jamesward) and Rust Developer Retreat Participants | |
| [C#](dotnet) | 10/11 ![tests](https://github.com/jamesward/easyracer/actions/workflows/dotnet.yaml/badge.svg) | [Jason De Lorme](https://github.com/delormej) | Scenario 10: CPU Not Pegged |
| [F# + Reactive Extensions](fsharp-reactive) | 10/11 ![tests](https://github.com/jamesward/easyracer/actions/workflows/fsharp-reactive.yaml/badge.svg) | [Jack Leow](https://github.com/jackgene) | |
| [F# + Reactive Extensions](fsharp-reactive) | 11/11 ![tests](https://github.com/jamesward/easyracer/actions/workflows/fsharp-reactive.yaml/badge.svg) | [Jack Leow](https://github.com/jackgene) | |
| [OCaml + Lwt + Cohttp](ocaml-cohttp-lwt) | 10/11 ![tests](https://github.com/jamesward/easyracer/actions/workflows/ocaml-cohttp-lwt.yaml/badge.svg) | [Puneeth Chaganti](https://github.com/punchagan) | |
| [OCaml + Eio + Cohttp](ocaml-cohttp-eio) | 10/11 ![tests](https://github.com/jamesward/easyracer/actions/workflows/ocaml-cohttp-eio.yaml/badge.svg) | [Puneeth Chaganti](https://github.com/punchagan) | |
| [Python + AIOHTTP + TaskGroup](python-aiohttp-taskgroup) | 9/11 ![tests](https://github.com/jamesward/easyracer/actions/workflows/python-aiohttp-taskgroup.yaml/badge.svg) | [James Ward](https://github.com/jamesward) [Bruce Eckel](https://github.com/BruceEckel) | Needs Scenario 10 Impl |
| [Python + RxPy](python-rxpy) | 10/11 ![tests](https://github.com/jamesward/easyracer/actions/workflows/python-rxpy.yaml/badge.svg) | [Jack Leow](https://github.com/jackgene) | |
| [Python + RxPy](python-rxpy) | 11/11 ![tests](https://github.com/jamesward/easyracer/actions/workflows/python-rxpy.yaml/badge.svg) | [Jack Leow](https://github.com/jackgene) | |
| [Go](go-stdlib) | 10/11 ![tests](https://github.com/jamesward/easyracer/actions/workflows/go-stdlib.yaml/badge.svg) | [Jack Leow](https://github.com/jackgene) | |
| [Go conc](go-conc) | 10/11 ![tests](https://github.com/jamesward/easyracer/actions/workflows/go-conc.yaml/badge.svg) | [Jack Leow](https://github.com/jackgene) | |
| [Swift + Grand Central Dispatch](swift-dispatch) | 10/11 ![tests](https://github.com/jamesward/easyracer/actions/workflows/swift-dispatch.yaml/badge.svg) | [Jack Leow](https://github.com/jackgene) | |
| [Swift + Grand Central Dispatch](swift-dispatch) | 11/11 ![tests](https://github.com/jamesward/easyracer/actions/workflows/swift-dispatch.yaml/badge.svg) | [Jack Leow](https://github.com/jackgene) | |
| [Swift + async/await](swift-async) | 11/11 ![tests](https://github.com/jamesward/easyracer/actions/workflows/swift-async.yaml/badge.svg) | [Jack Leow](https://github.com/jackgene) | |
| [Swift + Combine](swift-combine) | 10/11 ![tests](https://github.com/jamesward/easyracer/actions/workflows/swift-combine.yaml/badge.svg) | [Jack Leow](https://github.com/jackgene) | |
| [Elm](elm-worker) | 10/11 ![tests](https://github.com/jamesward/easyracer/actions/workflows/elm-worker.yaml/badge.svg) | [Jack Leow](https://github.com/jackgene) | |
| [Elm](elm-worker) | 11/11 ![tests](https://github.com/jamesward/easyracer/actions/workflows/elm-worker.yaml/badge.svg) | [Jack Leow](https://github.com/jackgene) | |
| [Swift + Combine](swift-combine) | 11/11 ![tests](https://github.com/jamesward/easyracer/actions/workflows/swift-combine.yaml/badge.svg) | [Jack Leow](https://github.com/jackgene) | |
| [JavaScript](javascript-stdlib) | 9/11 ![tests](https://github.com/jamesward/easyracer/actions/workflows/javascript-stdlib.yaml/badge.svg) | [James Ward](https://github.com/jamesward) | Needs Scenario 10 Impl |
| [Scala + Cats Effects 3](scala-ce3) | 9/11 ![tests](https://github.com/jamesward/easyracer/actions/workflows/scala-ce3.yaml/badge.svg) | [Paul Snively](https://github.com/paul-snively) | Needs Scenario 10 Impl |
| [Python + HTTPX + Trio](python-httpx-trio) | 8/11 ![tests](https://github.com/jamesward/easyracer/actions/workflows/python-httpx-trio.yaml/badge.svg) | [James Ward](https://github.com/jamesward) | Needs Scenarios 3, 10 |
Expand Down
94 changes: 94 additions & 0 deletions elm-worker/src/EasyRacer/Scenario11.elm
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
module EasyRacer.Scenario11 exposing (main)

-- Elm does not really have a higher-level racing construct
-- We are building everything by hand anyway, so this is basically just scenario 6

import EasyRacer.Ports as Ports
import Http
import Platform exposing (Program)
import Set exposing (Set)


type alias Flags =
String


type alias Model =
{ inflightTrackers : Set String
}


type Msg
= HttpResponse String (Result Http.Error String)


scenarioPath : String
scenarioPath =
"/11"


init : Flags -> ( Model, Cmd Msg )
init baseUrl =
let
requestTrackers =
[ "first", "second", "third" ]

httpRequest tracker =
{ method = "GET"
, headers = []
, url = baseUrl ++ scenarioPath
, body = Http.emptyBody
, expect = Http.expectString (HttpResponse tracker)
, timeout = Nothing
, tracker = Just tracker
}
in
( { inflightTrackers = Set.fromList requestTrackers
}
, requestTrackers
|> List.map (Http.request << httpRequest)
|> Cmd.batch
)


update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
HttpResponse tracker httpResult ->
let
remainingTrackers : Set String
remainingTrackers =
model.inflightTrackers |> Set.remove tracker
in
( { model | inflightTrackers = remainingTrackers }
, case httpResult of
Ok bodyText ->
let
cancellations : List (Cmd Msg)
cancellations =
remainingTrackers
|> Set.toList
|> List.map Http.cancel

returnResult : Cmd Msg
returnResult =
Ok bodyText |> Ports.sendResult
in
returnResult :: cancellations |> Cmd.batch

Err _ ->
if not <| Set.isEmpty remainingTrackers then
Cmd.none

else
Err "all requests completed without a single success response" |> Ports.sendResult
)


main : Program Flags Model Msg
main =
Platform.worker
{ init = init
, update = update
, subscriptions = always Sub.none
}
2 changes: 1 addition & 1 deletion elm-worker/tests/EasyRacer.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ describe("EasyRacer", () => {
await container.stop();
});

for (const idx of Array(10).keys()) {
for (const idx of Array(11).keys()) {
const scenarioNum = idx + 1;
it("scenario " + scenarioNum, async () => {
const name = "Scenario" + scenarioNum;
Expand Down
4 changes: 2 additions & 2 deletions fsharp-reactive/EasyRacer.Tests/EasyRacer.Tests.fsproj
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<TargetFramework>net9.0</TargetFramework>
<IsPackable>false</IsPackable>
<GenerateProgramFile>false</GenerateProgramFile>
<IsTestProject>true</IsTestProject>
Expand All @@ -24,4 +24,4 @@
<ItemGroup>
<ProjectReference Include="..\EasyRacer\EasyRacer.fsproj" />
</ItemGroup>
</Project>
</Project>
16 changes: 12 additions & 4 deletions fsharp-reactive/EasyRacer/EasyRacer.fs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ let scenario4 (scenarioGet: string -> IObservable<HttpResponseMessage>) : IObser

let reqWithTimeout =
req
|> Observable.timeoutSpan (TimeSpan.FromSeconds 1)
|> Observable.timeoutSpan (TimeSpan.FromSeconds 1.0)
|> Observable.take 1
|> Observable.catch Observable.empty

Expand Down Expand Up @@ -64,7 +64,7 @@ let scenario7 (scenarioGet: string -> IObservable<HttpResponseMessage>) : IObser
|> Observable.bind (fun resp -> resp.Content.ReadAsStringAsync() |> Async.AwaitTask |> Observable.ofAsync)

let reqWithDelay =
Observable.delay (TimeSpan.FromSeconds 3) (Observable.single ())
Observable.delay (TimeSpan.FromSeconds 3.0) (Observable.single ())
|> Observable.bind (fun () -> req)

Observable.merge req reqWithDelay |> Observable.take 1
Expand Down Expand Up @@ -142,7 +142,7 @@ let scenario10 (scenarioGet: string -> IObservable<HttpResponseMessage>) : IObse
->
Observable.single ($"bad HTTP status: {resp.StatusCode}")
| resp ->
Observable.delay (TimeSpan.FromSeconds 1) (Observable.single ())
Observable.delay (TimeSpan.FromSeconds 1.0) (Observable.single ())
|> Observable.bind (fun () -> reportProcessLoad endWallTime endCpuTime))

let reporter = reportProcessLoad DateTime.Now proc.TotalProcessorTime
Expand All @@ -154,6 +154,13 @@ let scenario10 (scenarioGet: string -> IObservable<HttpResponseMessage>) : IObse
|> Observable.filter (fun text -> text <> "")
|> Observable.take 1

let scenario11 (scenarioGet: string -> IObservable<HttpResponseMessage>) : IObservable<string> =
let req =
scenarioGet "/11"
|> Observable.bind (fun resp -> resp.Content.ReadAsStringAsync() |> Async.AwaitTask |> Observable.ofAsync)

Observable.merge req req |> Observable.merge req |> Observable.take 1

let scenarios: ((string -> IObservable<HttpResponseMessage>) -> IObservable<string>) array =
[| scenario1
scenario2
Expand All @@ -164,7 +171,8 @@ let scenarios: ((string -> IObservable<HttpResponseMessage>) -> IObservable<stri
scenario7
scenario8
scenario9
scenario10 |]
scenario10
scenario11 |]

[<EntryPoint>]
let main _ =
Expand Down
4 changes: 2 additions & 2 deletions fsharp-reactive/EasyRacer/EasyRacer.fsproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<TargetFramework>net9.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<Compile Include="EasyRacer.fs" />
Expand All @@ -10,4 +10,4 @@
<PackageReference Include="FSharp.Control.Reactive" Version="5.0.5" />
<PackageReference Include="FSharpx.Async" Version="1.14.1" />
</ItemGroup>
</Project>
</Project>
2 changes: 1 addition & 1 deletion java-loom/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ repositories {
}

dependencies {
testImplementation("org.junit.jupiter:junit-jupiter:5.11.3")
testImplementation("org.junit.jupiter:junit-jupiter:5.11.4")
testImplementation("org.testcontainers:testcontainers:1.20.4")
testImplementation("org.testcontainers:junit-jupiter:1.20.4")
testRuntimeOnly("org.slf4j:slf4j-simple:2.0.16")
Expand Down
2 changes: 1 addition & 1 deletion kotlin-arrow/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ application {

dependencies {
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.9.0")
implementation("io.ktor:ktor-client-core:3.0.2")
implementation("io.ktor:ktor-client-core:3.0.3")
implementation("io.ktor:ktor-client-java:3.0.2")
implementation("io.arrow-kt:arrow-fx-coroutines:2.0.0")
runtimeOnly("org.slf4j:slf4j-simple:2.0.16")
Expand Down
2 changes: 1 addition & 1 deletion kotlin-coroutines/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ application {

dependencies {
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.9.0")
implementation("io.ktor:ktor-client-core:3.0.2")
implementation("io.ktor:ktor-client-core:3.0.3")
implementation("io.ktor:ktor-client-java:3.0.2")

testImplementation("io.kotest:kotest-runner-junit5:5.9.1")
Expand Down
Loading

0 comments on commit 35e4eaf

Please sign in to comment.