)]}'
{
  "commit": "263a936b5a7c78fcba53714d9cca96c723596178",
  "tree": "81bb9d4976fb04829f15e84f76c763e60fc802f1",
  "parents": [
    "71640af5a7ef4d2c7861d10816ae259e4f11605c"
  ],
  "author": {
    "name": "吴晟 Wu Sheng",
    "email": "wu.sheng@foxmail.com",
    "time": "Sun Apr 12 23:43:14 2026 +0800"
  },
  "committer": {
    "name": "GitHub",
    "email": "noreply@github.com",
    "time": "Sun Apr 12 23:43:14 2026 +0800"
  },
  "message": "fix: support module-level @runnable with continue_tracing() (#391)\n\n## Summary\n\n`@runnable` previously captured the trace context snapshot at decoration time, which only worked when applied **inline** during an active request. Module-level `@runnable` (the natural Python pattern) silently broke cross-thread trace linking because the snapshot was `None` at import time.\n\n### Changes\n\n- `@runnable` now returns a `_RunnableWrapper` object with a `continue_tracing()` method\n- `continue_tracing()` captures the snapshot on the calling (parent) thread and returns a callable for use as `Thread` target — this enables module-level `@runnable`\n- `__call__` preserves the original behavior: uses the decoration-time snapshot for inline `@runnable` — **no breaking changes**\n\n### Usage\n\n**Module-level (new, previously broken):**\n```python\n@runnable(op\u003d\u0027/post\u0027)\ndef post():\n    requests.post(...)\n\n@app.route(\u0027/\u0027)\ndef hello():\n    thread \u003d Thread(target\u003dpost.continue_tracing())  # snapshot captured here\n    thread.start()\n```\n\n**Inline (unchanged, backward compatible):**\n```python\n@app.route(\u0027/\u0027)\ndef hello():\n    @runnable(op\u003d\u0027/post\u0027)  # snapshot captured at decoration time\n    def post():\n        requests.post(...)\n    thread \u003d Thread(target\u003dpost)\n    thread.start()\n```\n\nCloses https://github.com/apache/skywalking/issues/11605",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "d9fb211645a4d112d2bc5b36f0283995ba7ead19",
      "old_mode": 33188,
      "old_path": "skywalking/decorators.py",
      "new_id": "172c7bd7b99a1072e096e5414f07d30c7606cbe6",
      "new_mode": 33188,
      "new_path": "skywalking/decorators.py"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "b1312a0905c3c5e1ea44bb6b98886392e67295af",
      "new_mode": 33188,
      "new_path": "tests/plugin/web/sw_threading/__init__.py"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "a27fb997141919745e1f129d6118704b9617c157",
      "new_mode": 33188,
      "new_path": "tests/plugin/web/sw_threading/docker-compose.yml"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "fbb5ef2986824d4f3f6f0de98a0cc5221d4f0454",
      "new_mode": 33188,
      "new_path": "tests/plugin/web/sw_threading/expected.data.yml"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "8b137891791fe96927ad78e64b0aad7bded08bdc",
      "new_mode": 33188,
      "new_path": "tests/plugin/web/sw_threading/requirements.txt"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "b1312a0905c3c5e1ea44bb6b98886392e67295af",
      "new_mode": 33188,
      "new_path": "tests/plugin/web/sw_threading/services/__init__.py"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "fa7bfef14121a9aace98e6d5817098e36bac22f0",
      "new_mode": 33188,
      "new_path": "tests/plugin/web/sw_threading/services/consumer.py"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "79cc50d6eaa25076196232082498c0eb961afec1",
      "new_mode": 33188,
      "new_path": "tests/plugin/web/sw_threading/services/provider.py"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "5e4a23dd9a987ee21cbc9cf40e7347bfd58ca32f",
      "new_mode": 33188,
      "new_path": "tests/plugin/web/sw_threading/test_threading.py"
    }
  ]
}
