From 920cf73cbb894e6a7414904488f3ed0695d56deb Mon Sep 17 00:00:00 2001 From: WindSoilder Date: Thu, 14 Sep 2023 19:28:08 +0800 Subject: [PATCH] Improve background job.nu (#607) * add Q&A session in README, and add `--label`, `--group` flag to spawn, add `output` sub command to acquire output easily * make detailed to be a flag --- modules/background_task/README.md | 61 +++++++++++++++++++++++++++++++ modules/background_task/job.nu | 47 ++++++++++++++++++++---- 2 files changed, 100 insertions(+), 8 deletions(-) diff --git a/modules/background_task/README.md b/modules/background_task/README.md index 487a7579..d95d3746 100644 --- a/modules/background_task/README.md +++ b/modules/background_task/README.md @@ -21,4 +21,65 @@ use job.nu # clean pueued finished job > job clean +``` + +# Q&A +## How can I pass data to background job? + +The easiest way to do is pass it by environment variable, and you can use these variables in job. + +So don't do this, it doesn't work: +```nushell +let a = 3 +job spawn { + echo $a +} +``` + +Instead, doing this: +```nushell +let a = 3 +with-env {"a": 3} { + job spawn { + echo $env.a + } +} +``` + +But what if I want to pass nushell's structure data to background job? + +You can serialize it to env variable, and then deserialize it in background job. + +```nushell +let a = [1, 2, 3] +with-env {"a": ($a | to json)} { + job spawn { + let a = ($env.a | from json) + echo $a + } +} +``` + +## How can I reuse custom commands in background job? + +You can defined these custom commands in a module, then you can use the module inside the job. + +So don't do this, it won't work: +```nushell +def custom [] { echo 3 } +job spawn { + custom # custom is not defined +} +``` + +Instead, do this: +```nushell +# a.nu +export def custom [] { echo 3 } + +# main.nu +job spawn { + use a.nu + a custom +} ``` \ No newline at end of file diff --git a/modules/background_task/job.nu b/modules/background_task/job.nu index 8e073bc8..504b5390 100644 --- a/modules/background_task/job.nu +++ b/modules/background_task/job.nu @@ -3,15 +3,29 @@ # please note that a fresh nushell is spawned to execute the given command # So it doesn't inherit current scope's variables, custom commands, alias definition, except env variables which value can convert to string. # +# Note that the closure to spawn can't take arguments. And it only supports something like this: { echo 3 }, it have no parameter list. +# # e.g: # spawn { echo 3 } export def spawn [ command: closure # the command to spawn + --label(-l): string # the label of comand + --group(-g): string # the group name to spawn ] { let config_path = $nu.config-path let env_path = $nu.env-path let source_code = (view source $command | str trim -l -c '{' | str trim -r -c '}') - let job_id = (pueue add -p $"nu --config \"($config_path)\" --env-config \"($env_path)\" -c '($source_code)'") + mut args = [ + $"nu --config \"($config_path)\" --env-config \"($env_path)\" -c '($source_code)'", + ] + if $label != null { + $args = ($args | prepend ["--label", $label]) + } + if $group != null { + $args = ($args | prepend ["--group", $group]) + } + let job_id = (pueue add -p $args) + {"job_id": $job_id} } @@ -26,14 +40,31 @@ export def log [ | flatten status } +# get job's stdout. +export def output [ + id: int # id to fetch job's stdout +] { + log $id | get output.0 +} + # get job running status -export def status () { - pueue status --json - | from json - | get tasks - | transpose -i status - | flatten - | flatten status +export def status [ + --detailed(-d) # need to get detailed stauts? +] { + let output = ( + pueue status --json + | from json + | get tasks + | transpose -i status + | flatten + | flatten status + ) + + if not $detailed { + $output | select id label group Done? status? start? end? + } else { + $output + } } # kill specific job