diff --git a/docs/concepts/runner-group-and-task.md b/docs/concepts/runner-group-and-task.md
index fe3fd9ff..57dd7231 100644
--- a/docs/concepts/runner-group-and-task.md
+++ b/docs/concepts/runner-group-and-task.md
@@ -6,13 +6,23 @@ Runner, task, and group are some pretty simple but important concepts. Let's see
# Runner
+
+
+
Any task registered to Zrb Runner will be accessible from the CLI. You can import Zrb Runner like the following:
```python
from zrb import runner
```
-## Registering Tasks
+## Registering Tasks to Runner
Once you import a Zrb Runner, you can use it to register your task like the following:
@@ -29,7 +39,7 @@ To access the task, you can run the following command in your terminal:
zrb task
```
-## Registering Grouped Tasks
+## Registering Grouped Tasks to Runner
You can also put your Task under Task Groups
@@ -47,7 +57,7 @@ To access the grouped task, you can run the following command in your terminal:
zrb group task
```
-## Restrictions
+## Limitations And Restrictions
- You can only register a task once.
- Registered tasks cannot have the same names under the same group names.
@@ -106,17 +116,51 @@ runner.register(task_2) # OK, task_1 and task_2 are located under different grou
# Group
+
+
+
+
+ Put related Tasks under the same Group for better discoverability.
+
+
+
+
+
You can use Group to organize your Tasks. A Group will only be accessible from the CLI if at least one registered Task is under it.
-You can also put a Group under another Group.
+You can also put a Group under another Group. Hierarchically speaking, you can think of Task Groups as directories to organize your Tasks.
-Let's see some examples:
+The following are some built-in Tasks and Task Groups in Zrb.
+
+```
+zrb
+├── base64
+│ ├── decode
+│ └── encode
+├── devtool
+│ ├── install
+│ │ ├── aws
+│ │ ├── docker
+│ │ ├── gcloud
+│ │ ├── ...
+│ │ └── zsh
+├── explain
+│ ├── dry-principle
+│ ├── kiss-principle
+│ ├── solid-principle
+│ ├── ...
+│ └── zen-of-python
+├── ...
+└── watch-changes
+```
+
+Let's see how you can group your Zrb Tasks:
```python
from zrb import runner, Task, Group
util = Group(name='util')
-base64 = Group(name='base64', parent=util)
+base64 = Group(name='json', parent=util)
encode = Task(name='encode', group=base64)
runner.register(encode)
@@ -125,15 +169,26 @@ decode = Task(name='decode', group=base64)
runner.register(decode)
```
+In the example, you have a `json` Task Group under `util` Task Group. The `json` Task Group contains two Tasks: `encode` and `decode`.
+
To access both `encode` and `decode`, you can use the following command from the CLI:
```bash
-zrb util base64 encode
-zrb util base64 decode
+zrb util json encode
+zrb util json decode
```
# Task
+
+
+
+
+ Finishing a task: 10% skill, 90% not getting distracted by the internet.
+
+
+
+
Tasks are the most basic unit in Zrb. There are many Task Classes you can use to create a Task.
- [Task](../technical-documentation/tasks/task.md): General purpose class, usually created using [@python_task](../technical-documentation/tasks/python-task.md) decorator.
diff --git a/docs/concepts/task-lifecycle.md b/docs/concepts/task-lifecycle.md
index 7397a2f2..a4bbc22f 100644
--- a/docs/concepts/task-lifecycle.md
+++ b/docs/concepts/task-lifecycle.md
@@ -62,7 +62,33 @@ update_ubuntu = CmdTask(
runner.register(update_ubuntu)
```
-Now, whenever you run `zrb update-ubuntu` on a non-Linux machine, the Task will enter `ready` state without actually do the execution.
+Now, whenever you run `zrb update-ubuntu` on a non-Linux machine, the Task will enter `ready` state without actually doing the execution.
+
+# Long Running Task
+
+We often need to set Zrb Task as `ready` even though the process is still running. For example, when we run a web server. We can say a web server is `ready` when it serves HTTP requests correctly.
+
+Zrb Tasks has `checkers` attributes. This attribute helps you to define the current Task's readiness.
+
+Let's see the following example.
+
+```python
+from zrb import runner, CmdTask, HTTPChecker
+
+start_server = CmdTask(
+ name='start-server',
+ cmd='python -m http.server 8080',
+ checkers=[
+ HTTPChecker(port=8080)
+ ]
+)
+runner.register(start_server)
+```
+
+In the example, `start-server` is `ready` once a request to `http://localhost:8080` returns `HTTP response 200`.
+
+Zrb provides some built-in [checkers](specialized-tasks/checker.md) you can use.
+
# Handling Task Lifecycle
diff --git a/docs/concepts/task-upstream.md b/docs/concepts/task-upstream.md
index 4bc86c90..90802d52 100644
--- a/docs/concepts/task-upstream.md
+++ b/docs/concepts/task-upstream.md
@@ -133,6 +133,6 @@ Let's say you have a connection glitch while doing `upgrade`. Zrb will only retr
# Next
-Next, you can learn about [environments](environments.md) and [inputs](inputs.md).
+Next, you can learn about [inputs](inputs.md) and [environments](environments.md).
🔖 [Table of Contents](../README.md) / [Concepts](README.md)