Commits
Tarun Sukhani authored d02cca90c06
feat(jobs): carry the logging context and Lang to forked threads and jobs (PF-177) Play's ambient state lives in plain thread-locals and every request, job and forked task runs on a thread of its own, so a task an action handed to an executor, and every job, logged without request_id and its siblings. play.utils.ContextPropagator captures what registered ThreadLocalAccessors hold on the calling thread and applies it on the thread that does the work; wrap(Runnable|Callable) does capture, apply, run and put-back around a task. It restores the worker's previous values rather than clearing, so wraps nest and a pooled thread keeps a context of its own, and it restores also when an accessor throws. Two accessors are built in: the Log4j ThreadContext map and Lang. Request-scoped objects and JPA/JDBC state are deliberately not carried; an integration test pins that a job started from a request gets its own EntityManager. Jobs started with now(), in() or afterRequest() capture when the method is called (afterRequest() is submitted only after ActionInvoker has cleared the map) and apply the snapshot after before(), because preInit() clears Lang. Every run of every job, scheduled ones included, logs under a jobId of its own, and call() gives its thread back what it held, since synchronous and inline jobs run on their caller's thread. Lang.peek() is the one new hook: it reads the thread's language without resolving one, which Lang.get() would store and possibly set a cookie for. Behaviour change: a job started from a request now runs in the request's language when one had been resolved before the job was started. Docs: "Context propagation" in jobs.textile, the per-request context paragraph in logs.textile, and AGENTS.md. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KDUoh3KhBpfjXn4rV6H356