[{"data":1,"prerenderedAt":1122},["ShallowReactive",2],{"navigation_docs_en":3,"-en-queue-tasks":441,"-en-queue-tasks-surround":1117},[4,45,60,81,112,129,146,173,197,213,242,279,356,372,384,403,429],{"title":5,"icon":6,"path":7,"stem":8,"children":9,"page":44},"Getting Started","i-lucide-rocket","\u002Fen\u002Fgetting-started","en\u002F1.getting-started",[10,15,20,24,29,34,39],{"title":11,"path":12,"stem":13,"icon":14},"Introduction","\u002Fen\u002Fgetting-started\u002Fintroduction","en\u002F1.getting-started\u002F1.introduction","i-lucide-house",{"title":16,"path":17,"stem":18,"icon":19},"Coming from Laravel","\u002Fen\u002Fgetting-started\u002Fcoming-from-laravel","en\u002F1.getting-started\u002F2.coming-from-laravel","i-lucide-arrow-right-left",{"title":21,"path":22,"stem":23,"icon":19},"Coming from Symfony","\u002Fen\u002Fgetting-started\u002Fcoming-from-symfony","en\u002F1.getting-started\u002F3.coming-from-symfony",{"title":25,"path":26,"stem":27,"icon":28},"Installation","\u002Fen\u002Fgetting-started\u002Finstallation","en\u002F1.getting-started\u002F4.installation","i-lucide-download",{"title":30,"path":31,"stem":32,"icon":33},"Your first module","\u002Fen\u002Fgetting-started\u002Ffirst-module","en\u002F1.getting-started\u002F5.first-module","i-lucide-package-plus",{"title":35,"path":36,"stem":37,"icon":38},"Project structure","\u002Fen\u002Fgetting-started\u002Fproject-structure","en\u002F1.getting-started\u002F6.project-structure","i-lucide-folder-tree",{"title":40,"path":41,"stem":42,"icon":43},"The shop sample application","\u002Fen\u002Fgetting-started\u002Fsample-app","en\u002F1.getting-started\u002F7.sample-app","i-lucide-shopping-cart",false,{"title":46,"icon":47,"path":48,"stem":49,"children":50,"page":44},"queue","i-lucide-layers","\u002Fen\u002Fqueue","en\u002F10.queue",[51,56],{"title":52,"path":53,"stem":54,"icon":55},"Overview","\u002Fen\u002Fqueue\u002Foverview","en\u002F10.queue\u002F1.overview","i-lucide-list-ordered",{"title":57,"path":58,"stem":59,"icon":47},"Tasks","\u002Fen\u002Fqueue\u002Ftasks","en\u002F10.queue\u002F2.tasks",{"title":61,"icon":62,"path":63,"stem":64,"children":65,"page":44},"events","i-lucide-workflow","\u002Fen\u002Fevents","en\u002F11.events",[66,71,76],{"title":67,"path":68,"stem":69,"icon":70},"Events","\u002Fen\u002Fevents\u002Foverview","en\u002F11.events\u002F1.overview","i-lucide-radio",{"title":72,"path":73,"stem":74,"icon":75},"Outbox","\u002Fen\u002Fevents\u002Foutbox","en\u002F11.events\u002F2.outbox","i-lucide-inbox",{"title":77,"path":78,"stem":79,"icon":80},"Scheduling","\u002Fen\u002Fevents\u002Fscheduler","en\u002F11.events\u002F3.scheduler","i-lucide-calendar-clock",{"title":82,"icon":83,"path":84,"stem":85,"children":86,"page":44},"auth","i-lucide-shield-check","\u002Fen\u002Fauth","en\u002F12.auth",[87,92,97,102,107],{"title":88,"path":89,"stem":90,"icon":91},"Authentication","\u002Fen\u002Fauth\u002Foverview","en\u002F12.auth\u002F1.overview","i-lucide-key-round",{"title":93,"path":94,"stem":95,"icon":96},"RBAC","\u002Fen\u002Fauth\u002Frbac","en\u002F12.auth\u002F2.rbac","i-lucide-users",{"title":98,"path":99,"stem":100,"icon":101},"Policies","\u002Fen\u002Fauth\u002Fpolicy","en\u002F12.auth\u002F3.policy","i-lucide-gavel",{"title":103,"path":104,"stem":105,"icon":106},"Using auth standalone","\u002Fen\u002Fauth\u002Fstandalone","en\u002F12.auth\u002F4.standalone","i-lucide-plug",{"title":108,"path":109,"stem":110,"icon":111},"Social login with goth, standalone","\u002Fen\u002Fauth\u002Fsocial-standalone","en\u002F12.auth\u002F5.social-standalone","i-lucide-log-in",{"title":113,"icon":114,"path":115,"stem":116,"children":117,"page":44},"mail","i-lucide-mail","\u002Fen\u002Fmail","en\u002F13.mail",[118,121,125],{"title":52,"path":119,"stem":120,"icon":114},"\u002Fen\u002Fmail\u002Foverview","en\u002F13.mail\u002F1.overview",{"title":122,"path":123,"stem":124,"icon":114},"SMTP","\u002Fen\u002Fmail\u002Fsmtp","en\u002F13.mail\u002F2.smtp",{"title":126,"path":127,"stem":128,"icon":114},"MJML","\u002Fen\u002Fmail\u002Fmjml","en\u002F13.mail\u002F3.mjml",{"title":130,"icon":131,"path":132,"stem":133,"children":134,"page":44},"notify","i-lucide-bell","\u002Fen\u002Fnotify","en\u002F14.notify",[135,138,142],{"title":52,"path":136,"stem":137,"icon":131},"\u002Fen\u002Fnotify\u002Foverview","en\u002F14.notify\u002F1.overview",{"title":139,"path":140,"stem":141,"icon":131},"Database channel","\u002Fen\u002Fnotify\u002Fdatabase","en\u002F14.notify\u002F2.database",{"title":143,"path":144,"stem":145,"icon":131},"Broadcast channel","\u002Fen\u002Fnotify\u002Fbroadcast","en\u002F14.notify\u002F3.broadcast",{"title":147,"icon":148,"path":149,"stem":150,"children":151,"page":44},"storage","i-lucide-hard-drive","\u002Fen\u002Fstorage","en\u002F15.storage",[152,155,159,163,168],{"title":52,"path":153,"stem":154,"icon":148},"\u002Fen\u002Fstorage\u002Foverview","en\u002F15.storage\u002F1.overview",{"title":156,"path":157,"stem":158},"Disk API","\u002Fen\u002Fstorage\u002Fdisk-api","en\u002F15.storage\u002F2.disk-api",{"title":160,"path":161,"stem":162,"icon":148},"Memory and local disk","\u002Fen\u002Fstorage\u002Flocal","en\u002F15.storage\u002F3.local",{"title":164,"path":165,"stem":166,"icon":167},"S3","\u002Fen\u002Fstorage\u002Fs3","en\u002F15.storage\u002F4.s3","i-lucide-cloud",{"title":169,"path":170,"stem":171,"icon":172},"Testing","\u002Fen\u002Fstorage\u002Ftesting","en\u002F15.storage\u002F5.testing","i-lucide-flask-conical",{"title":174,"icon":175,"path":176,"stem":177,"children":178,"page":44},"telemetry","i-lucide-activity","\u002Fen\u002Ftelemetry","en\u002F16.telemetry",[179,182,187,192],{"title":52,"path":180,"stem":181,"icon":175},"\u002Fen\u002Ftelemetry\u002Foverview","en\u002F16.telemetry\u002F1.overview",{"title":183,"path":184,"stem":185,"icon":186},"Logging","\u002Fen\u002Ftelemetry\u002Flogging","en\u002F16.telemetry\u002F2.logging","i-lucide-scroll-text",{"title":188,"path":189,"stem":190,"icon":191},"OpenTelemetry","\u002Fen\u002Ftelemetry\u002Fopentelemetry","en\u002F16.telemetry\u002F3.opentelemetry","i-lucide-radar",{"title":193,"path":194,"stem":195,"icon":196},"Sentry","\u002Fen\u002Ftelemetry\u002Fsentry","en\u002F16.telemetry\u002F4.sentry","i-lucide-bug",{"title":198,"icon":199,"path":200,"stem":201,"children":202,"page":44},"Reference","i-lucide-book-open","\u002Fen\u002Freference","en\u002F17.reference",[203,208],{"title":204,"path":205,"stem":206,"icon":207},"Configuration","\u002Fen\u002Freference\u002Fconfiguration","en\u002F17.reference\u002F1.configuration","i-lucide-settings",{"title":209,"path":210,"stem":211,"icon":212},"External dependencies","\u002Fen\u002Freference\u002Fdependencies","en\u002F17.reference\u002F2.dependencies","i-lucide-package",{"title":214,"icon":215,"path":216,"stem":217,"children":218,"page":44},"Concepts","i-lucide-lightbulb","\u002Fen\u002Fconcepts","en\u002F2.concepts",[219,223,228,232,237],{"title":220,"path":221,"stem":222,"icon":47},"Architecture","\u002Fen\u002Fconcepts\u002Farchitecture","en\u002F2.concepts\u002F1.architecture",{"title":224,"path":225,"stem":226,"icon":227},"Error model","\u002Fen\u002Fconcepts\u002Ferror-model","en\u002F2.concepts\u002F2.error-model","i-lucide-shield-alert",{"title":204,"path":229,"stem":230,"icon":231},"\u002Fen\u002Fconcepts\u002Fconfiguration","en\u002F2.concepts\u002F3.configuration","i-lucide-settings-2",{"title":233,"path":234,"stem":235,"icon":236},"Codegen pipeline","\u002Fen\u002Fconcepts\u002Fcodegen-pipeline","en\u002F2.concepts\u002F4.codegen-pipeline","i-lucide-file-json",{"title":238,"path":239,"stem":240,"icon":241},"Design patterns","\u002Fen\u002Fconcepts\u002Fdesign-patterns","en\u002F2.concepts\u002F5.design-patterns","i-lucide-puzzle",{"title":243,"icon":244,"path":245,"stem":246,"children":247,"page":44},"Kit","i-lucide-box","\u002Fen\u002Fkit","en\u002F3.kit",[248,251,256,261,266,270,275],{"title":52,"path":249,"stem":250,"icon":244},"\u002Fen\u002Fkit\u002Foverview","en\u002F3.kit\u002F1.overview",{"title":252,"path":253,"stem":254,"icon":255},"Application lifecycle","\u002Fen\u002Fkit\u002Fapp","en\u002F3.kit\u002F2.app","i-lucide-power",{"title":257,"path":258,"stem":259,"icon":260},"Server","\u002Fen\u002Fkit\u002Fserver","en\u002F3.kit\u002F3.server","i-lucide-server",{"title":262,"path":263,"stem":264,"icon":265},"Worker","\u002Fen\u002Fkit\u002Fworker","en\u002F3.kit\u002F4.worker","i-lucide-cog",{"title":267,"path":268,"stem":269,"icon":70},"Realtime","\u002Fen\u002Fkit\u002Frealtime","en\u002F3.kit\u002F5.realtime",{"title":271,"path":272,"stem":273,"icon":274},"Migrations","\u002Fen\u002Fkit\u002Fmigrations","en\u002F3.kit\u002F6.migrations","i-lucide-file-stack",{"title":276,"path":277,"stem":278,"icon":111},"Social login","\u002Fen\u002Fkit\u002Fsocial-login","en\u002F3.kit\u002F7.social-login",{"title":280,"icon":281,"path":282,"stem":283,"children":284,"page":44},"CLI Reference","i-lucide-terminal","\u002Fen\u002Fcli","en\u002F4.cli",[285,288,293,298,303,308,313,318,323,328,333,337,342,347,351],{"title":52,"path":286,"stem":287,"icon":281},"\u002Fen\u002Fcli\u002Foverview","en\u002F4.cli\u002F1.overview",{"title":289,"path":290,"stem":291,"icon":292},"add db","\u002Fen\u002Fcli\u002Fadd-db","en\u002F4.cli\u002F10.add-db","i-lucide-database-zap",{"title":294,"path":295,"stem":296,"icon":297},"add compose \u002F add docker","\u002Fen\u002Fcli\u002Fadd-compose","en\u002F4.cli\u002F11.add-compose","i-lucide-container",{"title":299,"path":300,"stem":301,"icon":302},"add mail","\u002Fen\u002Fcli\u002Fadd-mail","en\u002F4.cli\u002F12.add-mail","i-lucide-mail-plus",{"title":304,"path":305,"stem":306,"icon":307},"add notification","\u002Fen\u002Fcli\u002Fadd-notification","en\u002F4.cli\u002F13.add-notification","i-lucide-bell-plus",{"title":309,"path":310,"stem":311,"icon":312},"add realtime","\u002Fen\u002Fcli\u002Fadd-realtime","en\u002F4.cli\u002F14.add-realtime","i-lucide-radio-tower",{"title":314,"path":315,"stem":316,"icon":317},"add seeder","\u002Fen\u002Fcli\u002Fadd-seeder","en\u002F4.cli\u002F15.add-seeder","i-lucide-sprout",{"title":319,"path":320,"stem":321,"icon":322},"new project","\u002Fen\u002Fcli\u002Fnew-project","en\u002F4.cli\u002F2.new-project","i-lucide-folder-plus",{"title":324,"path":325,"stem":326,"icon":327},"new module","\u002Fen\u002Fcli\u002Fnew-module","en\u002F4.cli\u002F3.new-module","i-lucide-blocks",{"title":329,"path":330,"stem":331,"icon":332},"add surface","\u002Fen\u002Fcli\u002Fadd-surface","en\u002F4.cli\u002F4.add-surface","i-lucide-layers-2",{"title":334,"path":335,"stem":336,"icon":244},"add core","\u002Fen\u002Fcli\u002Fadd-core","en\u002F4.cli\u002F5.add-core",{"title":338,"path":339,"stem":340,"icon":341},"add handler","\u002Fen\u002Fcli\u002Fadd-handler","en\u002F4.cli\u002F6.add-handler","i-lucide-webhook",{"title":343,"path":344,"stem":345,"icon":346},"new migration","\u002Fen\u002Fcli\u002Fnew-migration","en\u002F4.cli\u002F7.new-migration","i-lucide-file-plus",{"title":348,"path":349,"stem":350,"icon":265},"worker generators","\u002Fen\u002Fcli\u002Fworker-generators","en\u002F4.cli\u002F8.worker-generators",{"title":352,"path":353,"stem":354,"icon":355},"upgrade templates","\u002Fen\u002Fcli\u002Fupgrade-templates","en\u002F4.cli\u002F9.upgrade-templates","i-lucide-refresh-cw",{"title":357,"icon":227,"path":358,"stem":359,"children":360,"page":44},"errs","\u002Fen\u002Ferrs","en\u002F5.errs",[361,364,368],{"title":52,"path":362,"stem":363,"icon":227},"\u002Fen\u002Ferrs\u002Foverview","en\u002F5.errs\u002F1.overview",{"title":365,"path":366,"stem":367},"API","\u002Fen\u002Ferrs\u002Fapi","en\u002F5.errs\u002F2.api",{"title":369,"path":370,"stem":371,"icon":227},"Integration","\u002Fen\u002Ferrs\u002Fintegration","en\u002F5.errs\u002F3.integration",{"title":373,"icon":231,"path":374,"stem":375,"children":376,"page":44},"envconf","\u002Fen\u002Fenvconf","en\u002F6.envconf",[377,380],{"title":52,"path":378,"stem":379,"icon":231},"\u002Fen\u002Fenvconf\u002Foverview","en\u002F6.envconf\u002F1.overview",{"title":381,"path":382,"stem":383},"Recipes","\u002Fen\u002Fenvconf\u002Frecipes","en\u002F6.envconf\u002F2.recipes",{"title":385,"icon":386,"path":387,"stem":388,"children":389,"page":44},"httperr","i-lucide-globe","\u002Fen\u002Fhttperr","en\u002F7.httperr",[390,393,398],{"title":52,"path":391,"stem":392,"icon":386},"\u002Fen\u002Fhttperr\u002Foverview","en\u002F7.httperr\u002F1.overview",{"title":394,"path":395,"stem":396,"icon":397},"Error responses","\u002Fen\u002Fhttperr\u002Ferror-responses","en\u002F7.httperr\u002F2.error-responses","i-lucide-octagon-alert",{"title":399,"path":400,"stem":401,"icon":402},"Validation","\u002Fen\u002Fhttperr\u002Fvalidation","en\u002F7.httperr\u002F3.validation","i-lucide-badge-check",{"title":404,"icon":405,"path":406,"stem":407,"children":408,"page":44},"dbx","i-lucide-database","\u002Fen\u002Fdbx","en\u002F8.dbx",[409,412,416,420,425],{"title":52,"path":410,"stem":411,"icon":405},"\u002Fen\u002Fdbx\u002Foverview","en\u002F8.dbx\u002F1.overview",{"title":413,"path":414,"stem":415,"icon":106},"pgx","\u002Fen\u002Fdbx\u002Fpg","en\u002F8.dbx\u002F2.pg",{"title":417,"path":418,"stem":419,"icon":47},"bun","\u002Fen\u002Fdbx\u002Fbunx","en\u002F8.dbx\u002F3.bunx",{"title":421,"path":422,"stem":423,"icon":424},"Transactions","\u002Fen\u002Fdbx\u002Ftransactions","en\u002F8.dbx\u002F4.transactions","i-lucide-git-merge",{"title":426,"path":427,"stem":428,"icon":317},"Seeders","\u002Fen\u002Fdbx\u002Fseed","en\u002F8.dbx\u002F5.seed",{"title":430,"icon":55,"path":431,"stem":432,"children":433,"page":44},"paginate","\u002Fen\u002Fpaginate","en\u002F9.paginate",[434,437],{"title":52,"path":435,"stem":436,"icon":55},"\u002Fen\u002Fpaginate\u002Foverview","en\u002F9.paginate\u002F1.overview",{"title":438,"path":439,"stem":440,"icon":19},"Cursor pagination","\u002Fen\u002Fpaginate\u002Fcursor","en\u002F9.paginate\u002F2.cursor",{"id":442,"title":57,"body":443,"description":1110,"extension":1111,"links":1112,"meta":1113,"navigation":1114,"path":58,"seo":1115,"stem":59,"__hash__":1116},"docs_en\u002Fen\u002F10.queue\u002F2.tasks.md",{"type":444,"value":445,"toc":1102},"minimark",[446,480,485,490,607,628,704,718,722,729,871,890,895,926,930,936,1013,1044,1048,1098],[447,448,449,450,458,459,462,463,466,467,469,470,472,473,476,477,479],"p",{},"The ",[451,452,454],"a",{"href":453},"\u002Fen\u002Fqueue\u002Foverview#client",[455,456,457],"code",{},"Client"," and its ",[455,460,461],{},"Enqueue"," method are enough to submit a raw ",[455,464,465],{},"*asynq.Task",", but every layer built on ",[455,468,46],{},", from the ",[451,471,61],{"href":68}," module's listener fan-out to the ",[451,474,475],{"href":78},"scheduler","'s cron entries, shares three more things: a common set of enqueue options, a common envelope format for event payloads, and a common task-type naming scheme. This page covers all three; day to day you'll meet them again, unchanged, wherever ",[455,478,46],{}," is used underneath.",[481,482,484],"h2",{"id":483},"enqueue-options","Enqueue options",[447,486,487,489],{},[455,488,46],{}," re-exports the useful subset of asynq's options so common cases don't require importing asynq:",[491,492,493,506],"table",{},[494,495,496],"thead",{},[497,498,499,503],"tr",{},[500,501,502],"th",{},"Option",[500,504,505],{},"Effect",[507,508,509,527,537,547,557,570,580,593],"tbody",{},[497,510,511,517],{},[512,513,514],"td",{},[455,515,516],{},"OnQueue(name)",[512,518,519,520,523,524],{},"routes to a named queue (matched against the worker's ",[455,521,522],{},"WORKER_QUEUES"," weights); unset means ",[455,525,526],{},"default",[497,528,529,534],{},[512,530,531],{},[455,532,533],{},"MaxRetry(n)",[512,535,536],{},"how many retries before a failing task is archived",[497,538,539,544],{},[512,540,541],{},[455,542,543],{},"Timeout(d)",[512,545,546],{},"bounds a single execution attempt",[497,548,549,554],{},[512,550,551],{},[455,552,553],{},"Deadline(t)",[512,555,556],{},"absolute deadline across all attempts",[497,558,559,564],{},[512,560,561],{},[455,562,563],{},"ProcessIn(d)",[512,565,566,567],{},"delays processing by ",[455,568,569],{},"d",[497,571,572,577],{},[512,573,574],{},[455,575,576],{},"Unique(ttl)",[512,578,579],{},"suppresses an identical task (same type + payload) while a previous one is pending",[497,581,582,587],{},[512,583,584],{},[455,585,586],{},"Retention(d)",[512,588,589,590,592],{},"keeps the completed task in Valkey for ",[455,591,569],{},", for inspection",[497,594,595,600],{},[512,596,597],{},[455,598,599],{},"TaskID(id)",[512,601,602,603,606],{},"explicit task ID; a conflict surfaces as ",[455,604,605],{},"ErrDuplicate"," (the basis of idempotent delivery)",[447,608,609,610,614,615,621,622,624,625,627],{},"The options look the same everywhere a task is born: at ",[451,611,612],{"href":453},[455,613,461],{},", at the ",[451,616,618],{"href":617},"\u002Fen\u002Fevents\u002Foverview#listeners",[455,619,620],{},"events.Listen"," listener registration, and on ",[451,623,475],{"href":78}," entries. The shop's ",[455,626,113],{}," queue, for example, appears in the listener registration:",[629,630,635],"pre",{"className":631,"code":632,"language":633,"meta":634,"style":634},"language-go shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","events.Listen(reg, \"sendOrderConfirmation\", sendOrderConfirmation(deps), queue.OnQueue(\"mail\"))\n","go","",[455,636,637],{"__ignoreMap":634},[638,639,642,645,649,653,656,659,662,665,669,672,674,677,679,682,685,688,690,693,695,697,699,701],"span",{"class":640,"line":641},"line",1,[638,643,61],{"class":644},"sTEyZ",[638,646,648],{"class":647},"sMK4o",".",[638,650,652],{"class":651},"s2Zo4","Listen",[638,654,655],{"class":647},"(",[638,657,658],{"class":644},"reg",[638,660,661],{"class":647},",",[638,663,664],{"class":647}," \"",[638,666,668],{"class":667},"sfazB","sendOrderConfirmation",[638,670,671],{"class":647},"\"",[638,673,661],{"class":647},[638,675,676],{"class":651}," sendOrderConfirmation",[638,678,655],{"class":647},[638,680,681],{"class":644},"deps",[638,683,684],{"class":647},"),",[638,686,687],{"class":644}," queue",[638,689,648],{"class":647},[638,691,692],{"class":651},"OnQueue",[638,694,655],{"class":647},[638,696,671],{"class":647},[638,698,113],{"class":667},[638,700,671],{"class":647},[638,702,703],{"class":647},"))\n",[447,705,706,707,710,711,714,715,717],{},"When you need the full asynq option set, ",[455,708,709],{},"queue.AsynqOptions(opts...)"," converts these into raw ",[455,712,713],{},"[]asynq.Option",", and asynq's own API remains open alongside ",[455,716,461],{},": an escape hatch, not a forbidden zone.",[481,719,721],{"id":720},"the-envelope","The Envelope",[447,723,724,725,728],{},"Every event task payload is the same wire format, ",[455,726,727],{},"queue.Envelope",":",[629,730,732],{"className":631,"code":731,"language":633,"meta":634,"style":634},"type Envelope struct {\n    ID         string            `json:\"id\"`         \u002F\u002F dispatch id, doubles as the asynq TaskID\n    Name       string            `json:\"name\"`       \u002F\u002F the event name (EventName())\n    Payload    json.RawMessage   `json:\"payload\"`    \u002F\u002F the JSON-encoded event value\n    Metadata   map[string]string `json:\"metadata,omitempty\"` \u002F\u002F W3C trace context\n    OccurredAt time.Time         `json:\"occurred_at\"`\n}\n",[455,733,734,749,772,790,815,842,865],{"__ignoreMap":634},[638,735,736,739,743,746],{"class":640,"line":641},[638,737,738],{"class":647},"type",[638,740,742],{"class":741},"sBMFI"," Envelope",[638,744,745],{"class":647}," struct",[638,747,748],{"class":647}," {\n",[638,750,752,755,759,762,765,768],{"class":640,"line":751},2,[638,753,754],{"class":644},"    ID         ",[638,756,758],{"class":757},"spNyl","string",[638,760,761],{"class":647},"            `",[638,763,764],{"class":667},"json:\"id\"",[638,766,767],{"class":647},"`",[638,769,771],{"class":770},"sHwdD","         \u002F\u002F dispatch id, doubles as the asynq TaskID\n",[638,773,775,778,780,782,785,787],{"class":640,"line":774},3,[638,776,777],{"class":644},"    Name       ",[638,779,758],{"class":757},[638,781,761],{"class":647},[638,783,784],{"class":667},"json:\"name\"",[638,786,767],{"class":647},[638,788,789],{"class":770},"       \u002F\u002F the event name (EventName())\n",[638,791,793,796,799,801,804,807,810,812],{"class":640,"line":792},4,[638,794,795],{"class":644},"    Payload    ",[638,797,798],{"class":741},"json",[638,800,648],{"class":647},[638,802,803],{"class":741},"RawMessage",[638,805,806],{"class":647},"   `",[638,808,809],{"class":667},"json:\"payload\"",[638,811,767],{"class":647},[638,813,814],{"class":770},"    \u002F\u002F the JSON-encoded event value\n",[638,816,818,821,824,826,829,831,834,837,839],{"class":640,"line":817},5,[638,819,820],{"class":644},"    Metadata   ",[638,822,823],{"class":647},"map[",[638,825,758],{"class":757},[638,827,828],{"class":647},"]",[638,830,758],{"class":757},[638,832,833],{"class":647}," `",[638,835,836],{"class":667},"json:\"metadata,omitempty\"",[638,838,767],{"class":647},[638,840,841],{"class":770}," \u002F\u002F W3C trace context\n",[638,843,845,848,851,853,856,859,862],{"class":640,"line":844},6,[638,846,847],{"class":644},"    OccurredAt ",[638,849,850],{"class":741},"time",[638,852,648],{"class":647},[638,854,855],{"class":741},"Time",[638,857,858],{"class":647},"         `",[638,860,861],{"class":667},"json:\"occurred_at\"",[638,863,864],{"class":647},"`\n",[638,866,868],{"class":640,"line":867},7,[638,869,870],{"class":647},"}\n",[447,872,873,874,877,878,881,882,885,886,889],{},"The envelope travels unchanged from the dispatcher (or the ",[451,875,876],{"href":73},"outbox",") through the fan-out task to every listener task: the listener sees the same ",[455,879,880],{},"ID",", payload and trace context the producer set. ",[455,883,884],{},"env.Task()"," renders it as the fan-out task; ",[455,887,888],{},"queue.DecodeEnvelope(task)"," unpacks it on the other side.",[891,892,894],"h3",{"id":893},"trace-propagation-across-the-queue","Trace propagation across the queue",[447,896,897,900,901,904,905,908,909,912,913,916,917,921,922,925],{},[455,898,899],{},"env.InjectTrace(ctx)"," writes the context's trace context into ",[455,902,903],{},"Metadata"," in W3C form (",[455,906,907],{},"traceparent","\u002F",[455,910,911],{},"tracestate","); on the worker side, ",[455,914,915],{},"env.ExtractTrace(ctx)"," continues the same trace. That makes the HTTP request → outbox → relay → worker → listener path ",[918,919,920],"strong",{},"a single trace",", in the shop from placing the order to the confirmation e-mail. The dispatchers and the worker middleware do this automatically; see the ",[451,923,924],{"href":189},"OpenTelemetry page"," for details.",[481,927,929],{"id":928},"task-types","Task types",[447,931,932,933,935],{},"Four task-type prefixes cover every task that flows through ",[455,934,46],{}," in the async category, and the helpers below are the single source of the wire names:",[491,937,938,951],{},[494,939,940],{},[497,941,942,945,948],{},[500,943,944],{},"Helper",[500,946,947],{},"Task type",[500,949,950],{},"Created by",[507,952,953,968,983,998],{},[497,954,955,960,965],{},[512,956,957],{},[455,958,959],{},"EventTaskType(name)",[512,961,962],{},[455,963,964],{},"event:shop.orderPlaced",[512,966,967],{},"dispatch \u002F outbox relay (the starting point of the fan-out)",[497,969,970,975,980],{},[512,971,972],{},[455,973,974],{},"ListenerTaskType(event, listener)",[512,976,977],{},[455,978,979],{},"listener:shop.orderPlaced:sendOrderConfirmation",[512,981,982],{},"the worker's fan-out handler, one per listener",[497,984,985,990,995],{},[512,986,987],{},[455,988,989],{},"ScheduleTaskType(name)",[512,991,992],{},[455,993,994],{},"schedule:shop.someEvent",[512,996,997],{},"the scheduler, when firing a scheduled event",[497,999,1000,1005,1010],{},[512,1001,1002],{},[455,1003,1004],{},"JobTaskType(name)",[512,1006,1007],{},[455,1008,1009],{},"job:shop.nightlySalesReport",[512,1011,1012],{},"the scheduler, when firing a scheduled job",[447,1014,1015,1016,1019,1020,908,1023,908,1026,908,1029,1032,1033,1036,1037,1040,1041,1043],{},"The kit's ",[451,1017,1018],{"href":263},"worker"," routes tasks to its four built-in handlers by these prefixes; the ",[455,1021,1022],{},"IsEventTaskType",[455,1024,1025],{},"IsListenerTaskType",[455,1027,1028],{},"IsJobTaskType",[455,1030,1031],{},"IsScheduleTaskType"," and ",[455,1034,1035],{},"JobName"," helpers give the same classification to anyone working with raw tasks (say, in a handler registered via ",[455,1038,1039],{},"WithMux","). These are also the names you see in Asynqmon and in the worker's logs: you can tell at a glance which task is which listener of which event. The ",[451,1042,61],{"href":68}," module and the worker chassis are what actually produce and consume tasks under these names; this page only defines the naming, not the fan-out itself.",[481,1045,1047],{"id":1046},"when-to-reach-for-it-directly","When to reach for it directly",[1049,1050,1051,1074,1090],"ul",{},[1052,1053,1054,1057,1058,1061,1062,1067,1068,648],"li",{},[918,1055,1056],{},"Your own, non-event task",": build an ",[455,1059,1060],{},"asynq.NewTask(...)",", submit it with ",[451,1063,1064],{"href":453},[455,1065,1066],{},"client.Enqueue",", and register a handler for it in the worker ",[451,1069,1071,1072],{"href":1070},"\u002Fen\u002Fkit\u002Fworker#options","with ",[455,1073,1039],{},[1052,1075,1076,1079,1080,1083,1084,1086,1087,1089],{},[918,1077,1078],{},"An idempotent \"act exactly once\" enqueue",": ",[455,1081,1082],{},"TaskID"," + ",[455,1085,605],{}," handling, as on the ",[451,1088,52],{"href":453}," page.",[1052,1091,1092,1095,1096,648],{},[918,1093,1094],{},"Everything else"," (event dispatch, scheduling) belongs to the higher layers: start at ",[451,1097,61],{"href":68},[1099,1100,1101],"style",{},"html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}",{"title":634,"searchDepth":751,"depth":751,"links":1103},[1104,1105,1108,1109],{"id":483,"depth":751,"text":484},{"id":720,"depth":751,"text":721,"children":1106},[1107],{"id":893,"depth":774,"text":894},{"id":928,"depth":751,"text":929},{"id":1046,"depth":751,"text":1047},"Enqueue options, the event envelope, OTel trace propagation across the queue, and task-type naming conventions.","md",null,{},{"icon":47},{"title":57,"description":1110},"Cw7LwMc60V2WPZ_ZRLLjgIA5jx7LaH8byuXx7qd8USg",[1118,1120],{"title":52,"path":53,"stem":54,"description":1119,"icon":55,"children":-1},"The asynq + Valkey foundation: connection config, client and task enqueueing, that the whole async category builds on.",{"title":67,"path":68,"stem":69,"description":1121,"icon":70,"children":-1},"Events and listeners over asynq, every listener is an independent task with its own retry budget.",1785445894984]