<commit_before>package io.jooby.i2572;

import static org.junit.jupiter.api.Assertions.assertEquals;

import java.util.LinkedHashMap;
import java.util.Map;

import org.json.JSONObject;

import io.jooby.ExecutionMode;
import io.jooby.Jooby;
import io.jooby.json.JacksonModule;
import io.jooby.junit.ServerTest;
import io.jooby.junit.ServerTestRunner;

public class Issue2572 {

  private static class App2572 extends Jooby {
    Map<String, Object> state = new LinkedHashMap<>();

    {
      install(new JacksonModule());

      get("/2572/state", ctx -> state);

      decorator(next -> ctx -> {
        state.put("caller", Thread.currentThread().getName());
        ctx.onComplete(context -> {
          state.put("onComplete", Thread.currentThread().getName());
        });
        return next.apply(ctx);
      });

      get("/2572/init", ctx -> "Initialized");
    }
  }

  @ServerTest(executionMode = {ExecutionMode.EVENT_LOOP, ExecutionMode.WORKER})
  public void onCompleteShouldRunOnCallerThread(ServerTestRunner runner) {
    runner.use(App2572::new).ready(http -> {
      http.get("/2572/init", rsp -> {
        assertEquals("Initialized", rsp.body().string());
      });

      http.get("/2572/state", rsp -> {
        JSONObject json = new JSONObject(rsp.body().string());
        assertEquals(json.get("caller"), json.get("onComplete"));
      });
    });
  }
}<commit_msg>  build: fix random failure caused by raise condition<commit_after>package io.jooby.i2572;

import static org.junit.jupiter.api.Assertions.assertEquals;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CountDownLatch;

import org.json.JSONObject;

import io.jooby.json.JacksonModule;
import io.jooby.junit.ServerTest;
import io.jooby.junit.ServerTestRunner;

public class Issue2572 {

  @ServerTest
  public void onCompleteShouldRunOnCallerThread(ServerTestRunner runner) {
    runner.define(app -> {
      Map<String, Object> state = new ConcurrentHashMap<>();

      CountDownLatch latch = new CountDownLatch(1);
      app.install(new JacksonModule());

      app.get("/2572/state", ctx -> {
        latch.await();
        return state;
      });

      app.decorator(next -> ctx -> {
        state.put("caller", Thread.currentThread().getName());
        ctx.onComplete(context -> {
          state.put("onComplete", Thread.currentThread().getName());
          latch.countDown();
        });
        return next.apply(ctx);
      });

      app.get("/2572/init", ctx -> "Initialized");
    }).ready(http -> {
      http.get("/2572/init", rsp -> {
        System.out.println(Thread.currentThread());
        assertEquals("Initialized", rsp.body().string());
      });

      http.get("/2572/state", rsp -> {
        System.out.println(Thread.currentThread());
        JSONObject json = new JSONObject(rsp.body().string());
        System.out.println(json.get("caller") + " = " + json.get("onComplete"));
        assertEquals(json.get("caller"), json.get("onComplete"));
      });
    });
  }
}
{'fraction_non_alphanumeric': 0.1572700296735905, 'fraction_numerical': 0.018793273986152326, 'mean_word_length': 3.127891156462585, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 24, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4223496', 'n_tokens_mistral': 948, 'n_tokens_neox': 912, 'n_words': 154}