[{"data":1,"prerenderedAt":1636},["ShallowReactive",2],{"navigation":3,"\u002Factions-and-metrics\u002Fqueued-actions":307,"\u002Factions-and-metrics\u002Fqueued-actions-surround":1631},{"3.x":4,"2.x":203},[5,32,61,99,121,147,165],{"title":6,"icon":7,"path":8,"stem":9,"children":10,"page":31},"Getting Started","i-heroicons-star","\u002Fgetting-started","1.getting-started",[11,15,19,23,27],{"title":12,"path":13,"stem":14},"Introduction","\u002Fgetting-started\u002Fintroduction","1.getting-started\u002F1.introduction",{"title":16,"path":17,"stem":18},"Installation","\u002Fgetting-started\u002Finstallation","1.getting-started\u002F2.installation",{"title":20,"path":21,"stem":22},"Quick start","\u002Fgetting-started\u002Fquick-start","1.getting-started\u002F3.quick-start",{"title":24,"path":25,"stem":26},"Configuration","\u002Fgetting-started\u002Fconfiguration","1.getting-started\u002F4.configuration",{"title":28,"path":29,"stem":30},"Upgrade guide","\u002Fgetting-started\u002Fupgrade-guide","1.getting-started\u002F5.upgrade-guide",false,{"title":33,"icon":34,"path":35,"stem":36,"children":37,"page":31},"Resources","i-heroicons-document-text","\u002Fresources","2.resources",[38,41,45,49,53,57],{"title":33,"path":39,"stem":40},"\u002Fresources\u002Fresources","2.resources\u002F1.resources",{"title":42,"path":43,"stem":44},"Fields","\u002Fresources\u002Ffields","2.resources\u002F2.fields",{"title":46,"path":47,"stem":48},"Relationships","\u002Fresources\u002Frelations","2.resources\u002F3.relations",{"title":50,"path":51,"stem":52},"Validation","\u002Fresources\u002Fvalidation","2.resources\u002F4.validation",{"title":54,"path":55,"stem":56},"Perimeter","\u002Fresources\u002Fperimeter","2.resources\u002F5.perimeter",{"title":58,"path":59,"stem":60},"Limits","\u002Fresources\u002Flimits","2.resources\u002F6.limits",{"title":62,"icon":63,"path":64,"stem":65,"children":66,"page":31},"Search","i-heroicons-magnifying-glass","\u002Fsearch","3.search",[67,71,75,79,83,87,91,95],{"title":68,"path":69,"stem":70},"Search overview","\u002Fsearch\u002Foverview","3.search\u002F1.overview",{"title":72,"path":73,"stem":74},"Search filters","\u002Fsearch\u002Ffilters","3.search\u002F2.filters",{"title":76,"path":77,"stem":78},"Sorts and selects","\u002Fsearch\u002Fsorts-and-selects","3.search\u002F3.sorts-and-selects",{"title":80,"path":81,"stem":82},"Includes and aggregates","\u002Fsearch\u002Fincludes-and-aggregates","3.search\u002F4.includes-and-aggregates",{"title":84,"path":85,"stem":86},"Scopes and instructions","\u002Fsearch\u002Fscopes-and-instructions","3.search\u002F5.scopes-and-instructions",{"title":88,"path":89,"stem":90},"Text search","\u002Fsearch\u002Ftext-search","3.search\u002F6.text-search",{"title":92,"path":93,"stem":94},"Search engines","\u002Fsearch\u002Fsearch-engines","3.search\u002F7.search-engines",{"title":96,"path":97,"stem":98},"Searching outside HTTP","\u002Fsearch\u002Foutside-http","3.search\u002F8.outside-http",{"title":100,"icon":101,"path":102,"stem":103,"children":104,"page":31},"Writing","i-heroicons-pencil-square","\u002Fwriting","4.writing",[105,109,113,117],{"title":106,"path":107,"stem":108},"Mutate","\u002Fwriting\u002Fmutate","4.writing\u002F1.mutate",{"title":110,"path":111,"stem":112},"Writing relations","\u002Fwriting\u002Frelations","4.writing\u002F2.relations",{"title":114,"path":115,"stem":116},"Versioned rows","\u002Fwriting\u002Fversioned-rows","4.writing\u002F3.versioned-rows",{"title":118,"path":119,"stem":120},"Deleting and restoring","\u002Fwriting\u002Fdeleting","4.writing\u002F4.deleting",{"title":122,"icon":123,"path":124,"stem":125,"children":126,"page":31},"Actions and Metrics","i-heroicons-bolt","\u002Factions-and-metrics","5.actions-and-metrics",[127,131,135,139,143],{"title":128,"path":129,"stem":130},"Actions","\u002Factions-and-metrics\u002Factions","5.actions-and-metrics\u002F1.actions",{"title":132,"path":133,"stem":134},"Queued Actions","\u002Factions-and-metrics\u002Fqueued-actions","5.actions-and-metrics\u002F2.queued-actions",{"title":136,"path":137,"stem":138},"Confirmation","\u002Factions-and-metrics\u002Fconfirmation","5.actions-and-metrics\u002F3.confirmation",{"title":140,"path":141,"stem":142},"Metrics","\u002Factions-and-metrics\u002Fmetrics","5.actions-and-metrics\u002F4.metrics",{"title":144,"path":145,"stem":146},"Exports","\u002Factions-and-metrics\u002Fexports","5.actions-and-metrics\u002F5.exports",{"title":148,"icon":149,"path":150,"stem":151,"children":152,"page":31},"Authorization","i-heroicons-lock-closed","\u002Fauthorization","6.authorization",[153,157,161],{"title":154,"path":155,"stem":156},"Policies","\u002Fauthorization\u002Fpolicies","6.authorization\u002F1.policies",{"title":158,"path":159,"stem":160},"Gates","\u002Fauthorization\u002Fgates","6.authorization\u002F2.gates",{"title":162,"path":163,"stem":164},"Decision Cache","\u002Fauthorization\u002Fdecision-cache","6.authorization\u002F3.decision-cache",{"title":166,"icon":167,"path":168,"stem":169,"children":170,"page":31},"Digging Deeper","i-heroicons-list-bullet","\u002Fdigging-deeper","7.digging-deeper",[171,175,179,183,187,191,195,199],{"title":172,"path":173,"stem":174},"Details","\u002Fdigging-deeper\u002Fdetails","7.digging-deeper\u002F1.details",{"title":176,"path":177,"stem":178},"Events and Hooks","\u002Fdigging-deeper\u002Fevents-and-hooks","7.digging-deeper\u002F2.events-and-hooks",{"title":180,"path":181,"stem":182},"Custom Responses","\u002Fdigging-deeper\u002Fresponses","7.digging-deeper\u002F3.responses",{"title":184,"path":185,"stem":186},"OpenAPI Documentation","\u002Fdigging-deeper\u002Fopenapi","7.digging-deeper\u002F4.openapi",{"title":188,"path":189,"stem":190},"Precognition","\u002Fdigging-deeper\u002Fprecognition","7.digging-deeper\u002F5.precognition",{"title":192,"path":193,"stem":194},"Artisan Commands","\u002Fdigging-deeper\u002Fartisan","7.digging-deeper\u002F6.artisan",{"title":196,"path":197,"stem":198},"Laravel Boost Skill","\u002Fdigging-deeper\u002Fai-skill","7.digging-deeper\u002F7.ai-skill",{"title":200,"path":201,"stem":202},"Translations","\u002Fdigging-deeper\u002Ftranslations","7.digging-deeper\u002F8.translations",[204,215,237,260,297],{"title":6,"icon":7,"path":205,"stem":206,"children":207,"page":31},"\u002F2.x\u002Fgetting-started","2.x\u002F1.getting-started",[208,211],{"title":16,"path":209,"stem":210},"\u002F2.x\u002Fgetting-started\u002Finstallation","2.x\u002F1.getting-started\u002F1.installation",{"title":212,"path":213,"stem":214},"Upgrade Guide","\u002F2.x\u002Fgetting-started\u002Fupgrade-guide","2.x\u002F1.getting-started\u002F2.upgrade-guide",{"title":216,"icon":217,"path":218,"stem":219,"children":220,"page":31},"Endpoints","i-heroicons-arrow-uturn-left","\u002F2.x\u002Fendpoints","2.x\u002F2.endpoints",[221,224,227,230,233],{"title":172,"path":222,"stem":223},"\u002F2.x\u002Fendpoints\u002Fdetails","2.x\u002F2.endpoints\u002F1.details",{"title":62,"path":225,"stem":226},"\u002F2.x\u002Fendpoints\u002Fsearch","2.x\u002F2.endpoints\u002F2.search",{"title":106,"path":228,"stem":229},"\u002F2.x\u002Fendpoints\u002Fmutate","2.x\u002F2.endpoints\u002F3.mutate",{"title":128,"path":231,"stem":232},"\u002F2.x\u002Fendpoints\u002Factions","2.x\u002F2.endpoints\u002F4.actions",{"title":234,"path":235,"stem":236},"Delete","\u002F2.x\u002Fendpoints\u002Fdelete","2.x\u002F2.endpoints\u002F5.delete",{"title":33,"icon":34,"path":238,"stem":239,"children":240,"page":31},"\u002F2.x\u002Fresources","2.x\u002F3.resources",[241,245,249,252,256],{"title":242,"path":243,"stem":244},"Basics","\u002F2.x\u002Fresources\u002Fbasics","2.x\u002F3.resources\u002F1.basics",{"title":246,"path":247,"stem":248},"Exposed Data","\u002F2.x\u002Fresources\u002Fexposed-data","2.x\u002F3.resources\u002F2.exposed-data",{"title":46,"path":250,"stem":251},"\u002F2.x\u002Fresources\u002Frelationships","2.x\u002F3.resources\u002F3.relationships",{"title":253,"path":254,"stem":255},"Validations","\u002F2.x\u002Fresources\u002Fvalidations","2.x\u002F3.resources\u002F4.validations",{"title":257,"path":258,"stem":259},"Interactions","\u002F2.x\u002Fresources\u002Finteractions","2.x\u002F3.resources\u002F5.interactions",{"title":166,"icon":167,"path":261,"stem":262,"children":263,"page":31},"\u002F2.x\u002Fdigging-deeper","2.x\u002F4.digging-deeper",[264,267,271,274,278,282,286,290,294],{"title":128,"path":265,"stem":266},"\u002F2.x\u002Fdigging-deeper\u002Factions","2.x\u002F4.digging-deeper\u002F1.actions",{"title":268,"path":269,"stem":270},"Hooks","\u002F2.x\u002Fdigging-deeper\u002Fhooks","2.x\u002F4.digging-deeper\u002F2.hooks",{"title":158,"path":272,"stem":273},"\u002F2.x\u002Fdigging-deeper\u002Fgates","2.x\u002F4.digging-deeper\u002F3.gates",{"title":275,"path":276,"stem":277},"Authorizations","\u002F2.x\u002Fdigging-deeper\u002Fauthorizations","2.x\u002F4.digging-deeper\u002F4.authorizations",{"title":279,"path":280,"stem":281},"Full Text Search","\u002F2.x\u002Fdigging-deeper\u002Ffull-text-search","2.x\u002F4.digging-deeper\u002F5.full-text-search",{"title":283,"path":284,"stem":285},"Instructions","\u002F2.x\u002Fdigging-deeper\u002Finstructions","2.x\u002F4.digging-deeper\u002F6.instructions",{"title":287,"path":288,"stem":289},"Responses","\u002F2.x\u002Fdigging-deeper\u002Fresponses","2.x\u002F4.digging-deeper\u002F7.responses",{"title":291,"path":292,"stem":293},"Documentation","\u002F2.x\u002Fdigging-deeper\u002Fdocumentation","2.x\u002F4.digging-deeper\u002F8.documentation",{"title":188,"path":295,"stem":296},"\u002F2.x\u002Fdigging-deeper\u002Fprecognition","2.x\u002F4.digging-deeper\u002F9.precognition",{"title":298,"icon":299,"path":300,"stem":301,"children":302,"page":31},"Integrations","i-lucide-puzzle","\u002F2.x\u002Fintegrations","2.x\u002F5.integrations",[303],{"title":304,"path":305,"stem":306},"Flutter","\u002F2.x\u002Fintegrations\u002Fflutter","2.x\u002F5.integrations\u002F1.flutter",{"id":308,"title":132,"body":309,"description":1624,"extension":1625,"links":1626,"meta":1627,"navigation":444,"path":133,"seo":1628,"sitemap":1629,"stem":134,"__hash__":1630},"docs3x\u002F5.actions-and-metrics\u002F2.queued-actions.md",{"type":310,"value":311,"toc":1615},"minimark",[312,321,326,333,541,613,618,624,738,783,824,849,853,856,948,955,963,973,979,983,1002,1290,1298,1365,1395,1399,1405,1446,1457,1573,1611],[313,314,315,316,320],"p",{},"An action that takes time can run in queued jobs. The request reads the rows, puts their keys into one job per chunk, and answers at once. The worker runs ",[317,318,319],"code",{},"handle()"," as the user who sent the request.",[322,323,325],"h2",{"id":324},"queuing-an-action","Queuing an action",[313,327,328,329,332],{},"Implement ",[317,330,331],{},"ShouldQueue",":",[334,335,340],"pre",{"className":336,"code":337,"language":338,"meta":339,"style":339},"language-php shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","use Illuminate\\Contracts\\Queue\\ShouldQueue;\nuse Illuminate\\Support\\Collection;\nuse Lomkit\\Rest\\Actions\\Action;\nuse Lomkit\\Rest\\Actions\\ActionFields;\n\nclass ExportOrders extends Action implements ShouldQueue\n{\n    public function handle(ActionFields $fields, Collection $models): void\n    {\n        \u002F\u002F Runs in the worker, as the user who sent the request.\n    }\n}\n","php","",[317,341,342,374,393,417,439,446,469,475,516,522,529,535],{"__ignoreMap":339},[343,344,347,351,355,359,362,364,367,369,371],"span",{"class":345,"line":346},"line",1,[343,348,350],{"class":349},"sbssI","use",[343,352,354],{"class":353},"sTEyZ"," Illuminate",[343,356,358],{"class":357},"sMK4o","\\",[343,360,361],{"class":353},"Contracts",[343,363,358],{"class":357},[343,365,366],{"class":353},"Queue",[343,368,358],{"class":357},[343,370,331],{"class":353},[343,372,373],{"class":357},";\n",[343,375,377,379,381,383,386,388,391],{"class":345,"line":376},2,[343,378,350],{"class":349},[343,380,354],{"class":353},[343,382,358],{"class":357},[343,384,385],{"class":353},"Support",[343,387,358],{"class":357},[343,389,390],{"class":353},"Collection",[343,392,373],{"class":357},[343,394,396,398,401,403,406,408,410,412,415],{"class":345,"line":395},3,[343,397,350],{"class":349},[343,399,400],{"class":353}," Lomkit",[343,402,358],{"class":357},[343,404,405],{"class":353},"Rest",[343,407,358],{"class":357},[343,409,128],{"class":353},[343,411,358],{"class":357},[343,413,414],{"class":353},"Action",[343,416,373],{"class":357},[343,418,420,422,424,426,428,430,432,434,437],{"class":345,"line":419},4,[343,421,350],{"class":349},[343,423,400],{"class":353},[343,425,358],{"class":357},[343,427,405],{"class":353},[343,429,358],{"class":357},[343,431,128],{"class":353},[343,433,358],{"class":357},[343,435,436],{"class":353},"ActionFields",[343,438,373],{"class":357},[343,440,442],{"class":345,"line":441},5,[343,443,445],{"emptyLinePlaceholder":444},true,"\n",[343,447,449,453,457,460,463,466],{"class":345,"line":448},6,[343,450,452],{"class":451},"spNyl","class",[343,454,456],{"class":455},"sBMFI"," ExportOrders",[343,458,459],{"class":451}," extends",[343,461,462],{"class":455}," Action",[343,464,465],{"class":451}," implements",[343,467,468],{"class":455}," ShouldQueue\n",[343,470,472],{"class":345,"line":471},7,[343,473,474],{"class":357},"{\n",[343,476,478,481,484,488,491,493,496,499,502,505,507,510,513],{"class":345,"line":477},8,[343,479,480],{"class":451},"    public",[343,482,483],{"class":451}," function",[343,485,487],{"class":486},"s2Zo4"," handle",[343,489,490],{"class":357},"(",[343,492,436],{"class":455},[343,494,495],{"class":357}," $",[343,497,498],{"class":353},"fields",[343,500,501],{"class":357},",",[343,503,504],{"class":455}," Collection",[343,506,495],{"class":357},[343,508,509],{"class":353},"models",[343,511,512],{"class":357},"):",[343,514,515],{"class":349}," void\n",[343,517,519],{"class":345,"line":518},9,[343,520,521],{"class":357},"    {\n",[343,523,525],{"class":345,"line":524},10,[343,526,528],{"class":527},"sHwdD","        \u002F\u002F Runs in the worker, as the user who sent the request.\n",[343,530,532],{"class":345,"line":531},11,[343,533,534],{"class":357},"    }\n",[343,536,538],{"class":345,"line":537},12,[343,539,540],{"class":357},"}\n",[542,543,544,564,600,606],"ul",{},[545,546,547,548,551,552,555,556,559,560,563],"li",{},"The request pushes one ",[317,549,550],{},"Lomkit\\Rest\\Actions\\QueuedAction"," job per chunk of ",[317,553,554],{},"$chunkCount"," rows, and answers ",[317,557,558],{},"{\"data\": {\"impacted\": 250, \"result\": null}}",". ",[317,561,562],{},"impacted"," counts the rows put into the jobs.",[545,565,566,567,570,571,574,575,578,579,581,582,584,585,588,589,591,592,594,595,599],{},"One run creates at most ",[317,568,569],{},"rest.limits.sizes.jobs"," jobs, ",[317,572,573],{},"100"," by default and at least ",[317,576,577],{},"1",". When the rows need more jobs, each job takes the number of rows divided by that limit, rounded up, instead of ",[317,580,554],{},": 250 rows with a ",[317,583,554],{}," of ",[317,586,587],{},"2"," give 84 jobs of 3 rows, not 125 jobs. Raise ",[317,590,569],{}," when each job must keep ",[317,593,554],{}," rows, see ",[596,597,58],"a",{"href":598},"\u002Fresources\u002Flimits#queued-action-jobs",".",[545,601,602,605],{},[317,603,604],{},"respond()"," runs in the request, once the jobs are pushed.",[545,607,608,609,612],{},"In tests, assert ",[317,610,611],{},"Queue::assertPushed(QueuedAction::class)",". The job shows the action class as its name.",[614,615,617],"h3",{"id":616},"choosing-the-queue","Choosing the queue",[313,619,620,621,332],{},"Put Laravel's queue attributes on the action, or route the action class with ",[317,622,623],{},"Queue::route()",[334,625,627],{"className":336,"code":626,"language":338,"meta":339,"style":339},"use Illuminate\\Queue\\Attributes\\Queue;\nuse Illuminate\\Queue\\Attributes\\Tries;\n\n#[Queue('exports')]\n#[Tries(3)]\nclass ExportOrders extends Action implements ShouldQueue\n{\n    \u002F\u002F ...\n}\n",[317,628,629,650,671,675,697,711,725,729,734],{"__ignoreMap":339},[343,630,631,633,635,637,639,641,644,646,648],{"class":345,"line":346},[343,632,350],{"class":349},[343,634,354],{"class":353},[343,636,358],{"class":357},[343,638,366],{"class":353},[343,640,358],{"class":357},[343,642,643],{"class":353},"Attributes",[343,645,358],{"class":357},[343,647,366],{"class":353},[343,649,373],{"class":357},[343,651,652,654,656,658,660,662,664,666,669],{"class":345,"line":376},[343,653,350],{"class":349},[343,655,354],{"class":353},[343,657,358],{"class":357},[343,659,366],{"class":353},[343,661,358],{"class":357},[343,663,643],{"class":353},[343,665,358],{"class":357},[343,667,668],{"class":353},"Tries",[343,670,373],{"class":357},[343,672,673],{"class":345,"line":395},[343,674,445],{"emptyLinePlaceholder":444},[343,676,677,680,682,685,689,691,694],{"class":345,"line":419},[343,678,679],{"class":353},"#[Queue",[343,681,490],{"class":357},[343,683,684],{"class":357},"'",[343,686,688],{"class":687},"sfazB","exports",[343,690,684],{"class":357},[343,692,693],{"class":357},")",[343,695,696],{"class":353},"]\n",[343,698,699,702,704,707,709],{"class":345,"line":441},[343,700,701],{"class":353},"#[Tries",[343,703,490],{"class":357},[343,705,706],{"class":349},"3",[343,708,693],{"class":357},[343,710,696],{"class":353},[343,712,713,715,717,719,721,723],{"class":345,"line":448},[343,714,452],{"class":451},[343,716,456],{"class":455},[343,718,459],{"class":451},[343,720,462],{"class":455},[343,722,465],{"class":451},[343,724,468],{"class":455},[343,726,727],{"class":345,"line":471},[343,728,474],{"class":357},[343,730,731],{"class":345,"line":477},[343,732,733],{"class":527},"    \u002F\u002F ...\n",[343,735,736],{"class":345,"line":518},[343,737,540],{"class":357},[334,739,741],{"className":336,"code":740,"language":338,"meta":339,"style":339},"Queue::route(ExportOrders::class, 'exports', 'redis');\n",[317,742,743],{"__ignoreMap":339},[343,744,745,747,750,753,755,758,760,762,764,767,769,771,773,775,778,780],{"class":345,"line":346},[343,746,366],{"class":455},[343,748,749],{"class":357},"::",[343,751,752],{"class":486},"route",[343,754,490],{"class":357},[343,756,757],{"class":455},"ExportOrders",[343,759,749],{"class":357},[343,761,452],{"class":349},[343,763,501],{"class":357},[343,765,766],{"class":357}," '",[343,768,688],{"class":687},[343,770,684],{"class":357},[343,772,501],{"class":357},[343,774,766],{"class":357},[343,776,777],{"class":687},"redis",[343,779,684],{"class":357},[343,781,782],{"class":357},");\n",[313,784,785,788,789,788,792,788,795,788,798,788,801,788,804,807,808,811,812,815,816,819,820,823],{},[317,786,787],{},"#[Connection]",", ",[317,790,791],{},"#[Queue]",[317,793,794],{},"#[Delay]",[317,796,797],{},"#[Tries]",[317,799,800],{},"#[Timeout]",[317,802,803],{},"#[Backoff]",[317,805,806],{},"#[MaxExceptions]"," and ",[317,809,810],{},"#[FailOnTimeout]"," apply to the jobs of the action. An attribute wins over a route. An action has no ",[317,813,814],{},"$queue"," or ",[317,817,818],{},"$connection"," property and no ",[317,821,822],{},"dispatch()"," method.",[313,825,826,788,829,788,832,788,835,807,838,841,842,844,845,848],{},[317,827,828],{},"release()",[317,830,831],{},"attempts()",[317,833,834],{},"fail()",[317,836,837],{},"delete()",[317,839,840],{},"batch()"," work in ",[317,843,319],{},". An action that implements ",[317,846,847],{},"Illuminate\\Contracts\\Queue\\ShouldBeEncrypted"," gets its job payload encrypted, input values included.",[322,850,852],{"id":851},"what-the-worker-runs","What the worker runs",[313,854,855],{},"The job holds the resource class, the action class and key, the input values as the client sent them, the keys of the rows and a reference to the user. The worker builds the request context again:",[542,857,858,879,890,898,914,928],{},[545,859,860,863,864,866,867,870,871,874,875,878],{},[317,861,862],{},"$this->request()->user()"," returns the user who sent the request, in ",[317,865,319],{},", in ",[317,868,869],{},"perimeterQuery()"," and in the policies that the package checks. The worker logs nobody in: ",[317,872,873],{},"auth()->user()"," and the ",[317,876,877],{},"Gate"," facade see no user there.",[545,880,881,882,885,886,889],{},"The worker finds the action by its key among the ",[317,883,884],{},"actions()"," of the resource, so the options set when declaring it are kept, and casts the input values with ",[317,887,888],{},"fields()"," again.",[545,891,892,893,895,896,599],{},"The worker loads the rows by key through ",[317,894,869],{}," and the global scopes of the model. A row deleted or moved out of the perimeter before the job runs is skipped, and a job whose rows are all gone does not call ",[317,897,319],{},[545,899,900,901,807,904,907,908,910,911,599],{},"The worker loads the columns of the rows, without the ",[317,902,903],{},"includes",[317,905,906],{},"aggregates"," of the search. Load the relations that ",[317,909,319],{}," needs there: ",[317,912,913],{},"$models->load('author')",[545,915,916,917,920,921,924,925,927],{},"The rows were checked in the request with ",[317,918,919],{},"authorizeEach()",". The worker does not check them again: call ",[317,922,923],{},"$this->resource->authorizedTo('update', $model)"," in ",[317,926,319],{}," to check a row as it is when the job runs.",[545,929,930,931,933,934,937,938,944,945,599],{},"Each chunk runs in a transaction around ",[317,932,319],{},", unless the action uses ",[317,935,936],{},"ActionTransaction::None",". With ",[596,939,941],{"href":940},"\u002Factions-and-metrics\u002Factions#one-transaction-per-row",[317,942,943],{},"ActionTransaction::Row",", each row of the job runs in its own transaction around ",[317,946,947],{},"handleRow()",[313,949,950,951,954],{},"A job fails with ",[317,952,953],{},"Lomkit\\Rest\\Exceptions\\QueuedActionException"," when the user provider no longer finds the user, or when the resource no longer declares the action, for example after a deploy:",[334,956,961],{"className":957,"code":959,"language":960,"meta":339},[958],"language-text","The resource [App\\Rest\\Resources\\PostResource] no longer declares the action [App\\Rest\\Actions\\PublishPosts] under the key [publish-posts].\n","text",[317,962,959],{"__ignoreMap":339},[964,965,966],"warning",{},[313,967,968,969,972],{},"With several tenants, initialise the tenant in the worker before the job runs, as the ",[317,970,971],{},"QueueTenancyBootstrapper"," of stancl\u002Ftenancy 3 does from the job payload. The worker reads the user and the rows on the database connections that are current when the job runs.",[313,974,975,976,978],{},"Do not put a resource, an action or a request context in a job of your own: they cannot be serialized. Pass class names and keys. ",[317,977,436],{}," can be serialized: it keeps the cast values and finds the user again when it is unserialized.",[322,980,982],{"id":981},"batched-actions","Batched actions",[313,984,328,985,988,989,991,992,559,998,1001],{},[317,986,987],{},"Lomkit\\Rest\\Contracts\\BatchableAction"," next to ",[317,990,331],{}," to run the jobs in a ",[596,993,997],{"href":994,"rel":995},"https:\u002F\u002Flaravel.com\u002Fdocs\u002Fqueues#job-batching",[996],"nofollow","Laravel batch",[317,999,1000],{},"withBatch()"," registers the callbacks of the batch:",[334,1003,1005],{"className":336,"code":1004,"language":338,"meta":339,"style":339},"use Illuminate\\Bus\\Batch;\nuse Illuminate\\Bus\\PendingBatch;\nuse Illuminate\\Contracts\\Queue\\ShouldQueue;\nuse Lomkit\\Rest\\Actions\\Action;\nuse Lomkit\\Rest\\Actions\\ActionFields;\nuse Lomkit\\Rest\\Contracts\\BatchableAction;\nuse Throwable;\n\nclass ExportOrders extends Action implements ShouldQueue, BatchableAction\n{\n    public function withBatch(ActionFields $fields, PendingBatch $batch): void\n    {\n        $batch->then(function (Batch $batch) {\n            \u002F\u002F Every job ran.\n        })->catch(function (Batch $batch, Throwable $e) {\n            \u002F\u002F A job failed.\n        });\n    }\n}\n",[317,1006,1007,1025,1042,1062,1082,1102,1123,1132,1136,1156,1160,1191,1195,1228,1234,1268,1274,1280,1285],{"__ignoreMap":339},[343,1008,1009,1011,1013,1015,1018,1020,1023],{"class":345,"line":346},[343,1010,350],{"class":349},[343,1012,354],{"class":353},[343,1014,358],{"class":357},[343,1016,1017],{"class":353},"Bus",[343,1019,358],{"class":357},[343,1021,1022],{"class":353},"Batch",[343,1024,373],{"class":357},[343,1026,1027,1029,1031,1033,1035,1037,1040],{"class":345,"line":376},[343,1028,350],{"class":349},[343,1030,354],{"class":353},[343,1032,358],{"class":357},[343,1034,1017],{"class":353},[343,1036,358],{"class":357},[343,1038,1039],{"class":353},"PendingBatch",[343,1041,373],{"class":357},[343,1043,1044,1046,1048,1050,1052,1054,1056,1058,1060],{"class":345,"line":395},[343,1045,350],{"class":349},[343,1047,354],{"class":353},[343,1049,358],{"class":357},[343,1051,361],{"class":353},[343,1053,358],{"class":357},[343,1055,366],{"class":353},[343,1057,358],{"class":357},[343,1059,331],{"class":353},[343,1061,373],{"class":357},[343,1063,1064,1066,1068,1070,1072,1074,1076,1078,1080],{"class":345,"line":419},[343,1065,350],{"class":349},[343,1067,400],{"class":353},[343,1069,358],{"class":357},[343,1071,405],{"class":353},[343,1073,358],{"class":357},[343,1075,128],{"class":353},[343,1077,358],{"class":357},[343,1079,414],{"class":353},[343,1081,373],{"class":357},[343,1083,1084,1086,1088,1090,1092,1094,1096,1098,1100],{"class":345,"line":441},[343,1085,350],{"class":349},[343,1087,400],{"class":353},[343,1089,358],{"class":357},[343,1091,405],{"class":353},[343,1093,358],{"class":357},[343,1095,128],{"class":353},[343,1097,358],{"class":357},[343,1099,436],{"class":353},[343,1101,373],{"class":357},[343,1103,1104,1106,1108,1110,1112,1114,1116,1118,1121],{"class":345,"line":448},[343,1105,350],{"class":349},[343,1107,400],{"class":353},[343,1109,358],{"class":357},[343,1111,405],{"class":353},[343,1113,358],{"class":357},[343,1115,361],{"class":353},[343,1117,358],{"class":357},[343,1119,1120],{"class":353},"BatchableAction",[343,1122,373],{"class":357},[343,1124,1125,1127,1130],{"class":345,"line":471},[343,1126,350],{"class":349},[343,1128,1129],{"class":353}," Throwable",[343,1131,373],{"class":357},[343,1133,1134],{"class":345,"line":477},[343,1135,445],{"emptyLinePlaceholder":444},[343,1137,1138,1140,1142,1144,1146,1148,1151,1153],{"class":345,"line":518},[343,1139,452],{"class":451},[343,1141,456],{"class":455},[343,1143,459],{"class":451},[343,1145,462],{"class":455},[343,1147,465],{"class":451},[343,1149,1150],{"class":455}," ShouldQueue",[343,1152,501],{"class":357},[343,1154,1155],{"class":455}," BatchableAction\n",[343,1157,1158],{"class":345,"line":524},[343,1159,474],{"class":357},[343,1161,1162,1164,1166,1169,1171,1173,1175,1177,1179,1182,1184,1187,1189],{"class":345,"line":531},[343,1163,480],{"class":451},[343,1165,483],{"class":451},[343,1167,1168],{"class":486}," withBatch",[343,1170,490],{"class":357},[343,1172,436],{"class":455},[343,1174,495],{"class":357},[343,1176,498],{"class":353},[343,1178,501],{"class":357},[343,1180,1181],{"class":455}," PendingBatch",[343,1183,495],{"class":357},[343,1185,1186],{"class":353},"batch",[343,1188,512],{"class":357},[343,1190,515],{"class":349},[343,1192,1193],{"class":345,"line":537},[343,1194,521],{"class":357},[343,1196,1198,1201,1203,1206,1209,1211,1214,1217,1219,1221,1223,1225],{"class":345,"line":1197},13,[343,1199,1200],{"class":357},"        $",[343,1202,1186],{"class":353},[343,1204,1205],{"class":357},"->",[343,1207,1208],{"class":486},"then",[343,1210,490],{"class":357},[343,1212,1213],{"class":451},"function",[343,1215,1216],{"class":357}," (",[343,1218,1022],{"class":455},[343,1220,495],{"class":357},[343,1222,1186],{"class":353},[343,1224,693],{"class":357},[343,1226,1227],{"class":357}," {\n",[343,1229,1231],{"class":345,"line":1230},14,[343,1232,1233],{"class":527},"            \u002F\u002F Every job ran.\n",[343,1235,1237,1240,1243,1245,1247,1249,1251,1253,1255,1257,1259,1261,1264,1266],{"class":345,"line":1236},15,[343,1238,1239],{"class":357},"        })->",[343,1241,1242],{"class":486},"catch",[343,1244,490],{"class":357},[343,1246,1213],{"class":451},[343,1248,1216],{"class":357},[343,1250,1022],{"class":455},[343,1252,495],{"class":357},[343,1254,1186],{"class":353},[343,1256,501],{"class":357},[343,1258,1129],{"class":455},[343,1260,495],{"class":357},[343,1262,1263],{"class":353},"e",[343,1265,693],{"class":357},[343,1267,1227],{"class":357},[343,1269,1271],{"class":345,"line":1270},16,[343,1272,1273],{"class":527},"            \u002F\u002F A job failed.\n",[343,1275,1277],{"class":345,"line":1276},17,[343,1278,1279],{"class":357},"        });\n",[343,1281,1283],{"class":345,"line":1282},18,[343,1284,534],{"class":357},[343,1286,1288],{"class":345,"line":1287},19,[343,1289,540],{"class":357},[313,1291,1292,1293,807,1295,332],{},"The response gives the id of the batch, between ",[317,1294,562],{},[317,1296,1297],{},"result",[334,1299,1303],{"className":1300,"code":1301,"language":1302,"meta":339,"style":339},"language-json shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","{\"data\": {\"impacted\": 250, \"batch\": \"9f0c4d2e-5a1b-4c3d-8e7f-0a1b2c3d4e5f\", \"result\": null}}\n","json",[317,1304,1305],{"__ignoreMap":339},[343,1306,1307,1310,1313,1316,1318,1320,1323,1325,1327,1329,1331,1334,1336,1339,1341,1343,1345,1347,1350,1352,1354,1356,1358,1360,1362],{"class":345,"line":346},[343,1308,1309],{"class":357},"{",[343,1311,1312],{"class":357},"\"",[343,1314,1315],{"class":451},"data",[343,1317,1312],{"class":357},[343,1319,332],{"class":357},[343,1321,1322],{"class":357}," {",[343,1324,1312],{"class":357},[343,1326,562],{"class":455},[343,1328,1312],{"class":357},[343,1330,332],{"class":357},[343,1332,1333],{"class":349}," 250",[343,1335,501],{"class":357},[343,1337,1338],{"class":357}," \"",[343,1340,1186],{"class":455},[343,1342,1312],{"class":357},[343,1344,332],{"class":357},[343,1346,1338],{"class":357},[343,1348,1349],{"class":687},"9f0c4d2e-5a1b-4c3d-8e7f-0a1b2c3d4e5f",[343,1351,1312],{"class":357},[343,1353,501],{"class":357},[343,1355,1338],{"class":357},[343,1357,1297],{"class":455},[343,1359,1312],{"class":357},[343,1361,332],{"class":357},[343,1363,1364],{"class":357}," null}}\n",[542,1366,1367,1374,1387,1390],{},[545,1368,1369,1370,1373],{},"Read the batch with ",[317,1371,1372],{},"Bus::findBatch($id)",". The batch keeps the resource, the action and the user who started it in its options.",[545,1375,1376,1377,924,1380,1382,1383,1386],{},"The jobs skip their rows once the batch is cancelled: ",[317,1378,1379],{},"$this->batch()?->cancel()",[317,1381,319],{},", or ",[317,1384,1385],{},"Bus::findBatch($id)?->cancel()",", stops the jobs that did not run yet.",[545,1388,1389],{},"A batched action sends its batch to the connection and queue of its jobs.",[545,1391,1392,1394],{},[596,1393,144],{"href":145}," writes the rows of a search to a CSV file with a batched action.",[614,1396,1398],{"id":1397},"following-a-batch","Following a batch",[313,1400,1401,1404],{},[317,1402,1403],{},"withBatchProgress()"," adds a progress route to the resource:",[334,1406,1408],{"className":336,"code":1407,"language":338,"meta":339,"style":339},"Rest::resource('invoices', InvoiceController::class)->withBatchProgress();\n",[317,1409,1410],{"__ignoreMap":339},[343,1411,1412,1414,1416,1419,1421,1423,1426,1428,1430,1433,1435,1437,1440,1443],{"class":345,"line":346},[343,1413,405],{"class":455},[343,1415,749],{"class":357},[343,1417,1418],{"class":486},"resource",[343,1420,490],{"class":357},[343,1422,684],{"class":357},[343,1424,1425],{"class":687},"invoices",[343,1427,684],{"class":357},[343,1429,501],{"class":357},[343,1431,1432],{"class":455}," InvoiceController",[343,1434,749],{"class":357},[343,1436,452],{"class":349},[343,1438,1439],{"class":357},")->",[343,1441,1442],{"class":486},"withBatchProgress",[343,1444,1445],{"class":357},"();\n",[334,1447,1451],{"className":1448,"code":1449,"language":1450,"meta":339,"style":339},"language-http shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","GET \u002Fapi\u002Finvoices\u002Factions\u002Fexport-orders\u002Fbatches\u002F9f0c4d2e-5a1b-4c3d-8e7f-0a1b2c3d4e5f\n","http",[317,1452,1453],{"__ignoreMap":339},[343,1454,1455],{"class":345,"line":346},[343,1456,1449],{},[334,1458,1460],{"className":1300,"code":1459,"language":1302,"meta":339,"style":339},"{\"data\": {\"id\": \"9f0c4d2e-5a1b-4c3d-8e7f-0a1b2c3d4e5f\", \"total_jobs\": 3, \"pending_jobs\": 1, \"failed_jobs\": 0, \"progress\": 67, \"finished\": false, \"cancelled\": false}}\n",[317,1461,1462],{"__ignoreMap":339},[343,1463,1464,1466,1468,1470,1472,1474,1476,1478,1481,1483,1485,1487,1489,1491,1493,1495,1498,1500,1502,1505,1507,1509,1512,1514,1516,1519,1521,1523,1526,1528,1530,1533,1535,1537,1540,1542,1544,1547,1549,1551,1554,1556,1558,1561,1563,1566,1568,1570],{"class":345,"line":346},[343,1465,1309],{"class":357},[343,1467,1312],{"class":357},[343,1469,1315],{"class":451},[343,1471,1312],{"class":357},[343,1473,332],{"class":357},[343,1475,1322],{"class":357},[343,1477,1312],{"class":357},[343,1479,1480],{"class":455},"id",[343,1482,1312],{"class":357},[343,1484,332],{"class":357},[343,1486,1338],{"class":357},[343,1488,1349],{"class":687},[343,1490,1312],{"class":357},[343,1492,501],{"class":357},[343,1494,1338],{"class":357},[343,1496,1497],{"class":455},"total_jobs",[343,1499,1312],{"class":357},[343,1501,332],{"class":357},[343,1503,1504],{"class":349}," 3",[343,1506,501],{"class":357},[343,1508,1338],{"class":357},[343,1510,1511],{"class":455},"pending_jobs",[343,1513,1312],{"class":357},[343,1515,332],{"class":357},[343,1517,1518],{"class":349}," 1",[343,1520,501],{"class":357},[343,1522,1338],{"class":357},[343,1524,1525],{"class":455},"failed_jobs",[343,1527,1312],{"class":357},[343,1529,332],{"class":357},[343,1531,1532],{"class":349}," 0",[343,1534,501],{"class":357},[343,1536,1338],{"class":357},[343,1538,1539],{"class":455},"progress",[343,1541,1312],{"class":357},[343,1543,332],{"class":357},[343,1545,1546],{"class":349}," 67",[343,1548,501],{"class":357},[343,1550,1338],{"class":357},[343,1552,1553],{"class":455},"finished",[343,1555,1312],{"class":357},[343,1557,332],{"class":357},[343,1559,1560],{"class":357}," false,",[343,1562,1338],{"class":357},[343,1564,1565],{"class":455},"cancelled",[343,1567,1312],{"class":357},[343,1569,332],{"class":357},[343,1571,1572],{"class":357}," false}}\n",[542,1574,1575,1582,1589,1600],{},[545,1576,1577,1578,1581],{},"The route is named ",[317,1579,1580],{},"{name}.batch",". It answers the user who started the batch, through the same guard.",[545,1583,1584,1585,1588],{},"Another user, a guest, another action and an unknown batch get a ",[317,1586,1587],{},"404",", and so does every batch started by a guest.",[545,1590,1591,1592,1595,1596,1599],{},"The route checks the abilities that the resource's ",[317,1593,1594],{},"abilities()"," returns for ",[317,1597,1598],{},"Endpoint::Batch",", none by default.",[545,1601,1602,1604,1605,1608,1609,599],{},[317,1603,1539],{}," goes from ",[317,1606,1607],{},"0"," to ",[317,1610,573],{},[1612,1613,1614],"style",{},"html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}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 .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}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}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 .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}",{"title":339,"searchDepth":346,"depth":376,"links":1616},[1617,1620,1621],{"id":324,"depth":376,"text":325,"children":1618},[1619],{"id":616,"depth":395,"text":617},{"id":851,"depth":376,"text":852},{"id":981,"depth":376,"text":982,"children":1622},[1623],{"id":1397,"depth":395,"text":1398},"Run an action in queued jobs, as the user who sent the request, and follow a batch from the client.","md",null,{},{"title":132,"description":1624},{"loc":133},"xSoomlhxGNb70HT71TKzE2ZZK87uug5KVtcoayJtLak",[1632,1634],{"title":128,"path":129,"stem":130,"description":1633,"children":-1},"Run your own code on the rows of a resource, with typed inputs, row checks, transactions and a result for the client.",{"title":136,"path":137,"stem":138,"description":1635,"children":-1},"Make the endpoint check that the user confirmed an action or a write before it runs, with a signed token and a 428 response.",1794181354940]