cli
cli copied to clipboard
[Enhancement] Improve experience for apps that only execute tasks.
There is a category of apps that never have a long-running process. Instead they house code to execute a task periodically. The needs of these apps are different than apps that house long-running processes in a number of ways.
- No need for a route
- No need to be started
There are also needs similar to long running apps that are not fulfilled by the existing task experience.
- Use a buildpack provided start command
- Stage new application source on push
An ideal workflow for handling task-only apps should mirror, as much as possible, the experience of pushing an app that has long-running processes. It’s useful to illustrate the differences in UX.
Deploy an app with long-running processes
cf push my-app
The app source is uploaded, staged, start command automatically stored, and started.
Deploy and execute a task only app
cf push my-app --no-route --instances 0
cf run-task my-app “some-command”
Points of interest:
- The deployer must know the trick of using
--instances 0
. Looking at this it’s not obvious even why this is needed. The answer is that the app bits must be staged, but the app should not be started and health-checked like a long running app. So instances 0 prevents the app from actually running anything. Not at all intuitive. - The command must be entered at the time of invoking the task. How does a user decide what command to use? Ideally the command can be specified by a buildpack. This means a user must inspect the API to uncover the start command to then copy and paste for every task invocation.
An improved UX
There is a definite opportunity to improve the UX here. I believe there are a handful of use cases to consider.
- The app is task-only and wants to use a buildpack defined command to perform a single job
- The app is task-only and has multiple jobs it can perform that it specifies in a manifest
- The app has both long-running processes and tasks
In all cases it is beneficial to encode the start command into the app definition to be used later. This feature is now enabled in the CF API using template processes when creating a task http://v3-apidocs.cloudfoundry.org/version/3.70.0/index.html#create-a-task.
This leads to these proposed UXs for the above use cases.
- The app is task-only and wants to use a buildpack defined command to perform a single job
cf push my-app --task
cf run-task my-app
This behavior relies on an agreed upon convention between buildpacks and CF. If a buildpack
detects a task based app, it will provide a process type of task
with the desired start
command.
If there is no process type task
then the above run-task
invocation would error.
- The app is task-only and has multiple jobs it can perform that it specifies in a manifest
cf push my-app --task
cf run-task --process batchjob1
cf run-task --process batchjob2
This behavior assumes the app specified processes named batchjob1
and batchjob2
via either a Procfile or manifest, with valid start commands.
- The app has both long-running processes and tasks
cf push my-app
cf run-task --process batchjob1
This behavior assumes the app has web
and batchjob1
process types defined.
Wrapping up
An alternative UX could be cf push my-app --type task. This might be more flexible if there were other types of push in the future, perhaps cf push my-app --type function for example.
Another interesting question that is raised looking at the existing command is the required COMMAND field.
cf run-task APP_NAME COMMAND [-k DISK] [-m MEMORY] [--name TASK_NAME]
In this proposal it could either become optional and remain as a positional arg to not break existing scripts.
cf run-task APP_NAME [COMMAND] [-k DISK] [-m MEMORY] [--name TASK_NAME] [--process PROCESS_TYPE]
Or it could move into a named flag.
cf run-task APP_NAME [--command COMMAND] [-k DISK] [-m MEMORY] [--name TASK_NAME] [--process PROCESS_TYPE]
I’d be happy to provide some PRs to enhance both the push and run-task commands, probably on the v7 side only. Any feedback greatly appreciated!