Skip to content

Commit

Permalink
Expand and clarify docs on persistent tasks (#297)
Browse files Browse the repository at this point in the history
  • Loading branch information
timholy authored Oct 10, 2024
1 parent 1b88ce9 commit 065f7d7
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 8 deletions.
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,13 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).


## Version [v0.8.8] - 2024-10-10

### Changed

- Improved the documentation of `test_persisten_tasks`. ([#297])


## Version [v0.8.7] - 2024-04-09

- Reverted [#285], which was originally released in [v0.8.6], but caused a regression. ([#287], [#288])
Expand Down Expand Up @@ -227,6 +234,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
[v0.8.5]: https://github.com/JuliaTesting/Aqua.jl/releases/tag/v0.8.5
[v0.8.6]: https://github.com/JuliaTesting/Aqua.jl/releases/tag/v0.8.6
[v0.8.7]: https://github.com/JuliaTesting/Aqua.jl/releases/tag/v0.8.7
[v0.8.8]: https://github.com/JuliaTesting/Aqua.jl/releases/tag/v0.8.8
[#93]: https://github.com/JuliaTesting/Aqua.jl/issues/93
[#103]: https://github.com/JuliaTesting/Aqua.jl/issues/103
[#113]: https://github.com/JuliaTesting/Aqua.jl/issues/113
Expand Down Expand Up @@ -274,3 +282,4 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
[#285]: https://github.com/JuliaTesting/Aqua.jl/issues/285
[#287]: https://github.com/JuliaTesting/Aqua.jl/issues/287
[#288]: https://github.com/JuliaTesting/Aqua.jl/issues/288
[#297]: https://github.com/JuliaTesting/Aqua.jl/issues/297
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "Aqua"
uuid = "4c88cf16-eb10-579e-8560-4a9242c79595"
authors = ["Takafumi Arakaki <aka.tkf@gmail.com> and contributors"]
version = "0.8.7"
version = "0.8.8"

[deps]
Compat = "34da2185-b29b-5c13-b0c7-acf172513d20"
Expand Down
70 changes: 63 additions & 7 deletions docs/src/persistent_tasks.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,24 @@ One consequence is that a package that launches
`Task`s in its `__init__` function may precompile successfully,
but block precompilation of any packages that depend on it.

The symptom of this problem is a message
```
◐ MyPackage: Waiting for background task / IO / timer. Interrupt to inspect...
```
that may appear during precompilation, with that precompilation process
"hanging" until you press Ctrl-C.

Aqua has checks to determine whether your package *causes* this problem.
Conversely, if you're a *victim* of this problem, it also has tools to help you
determine which of your dependencies is causing the problem.

## Example

Let's create a dummy package, `PkgA`, that launches a persistent `Task`:

```julia
module PkgA
const t = Ref{Any}() # to prevent the Timer from being garbage-collected
const t = Ref{Timer}() # used to prevent the Timer from being garbage-collected
__init__() = t[] = Timer(0.1; interval=1) # create a persistent `Timer` `Task`
end
```
Expand All @@ -32,16 +43,31 @@ fails to precompile: `using PkgA` runs `PkgA.__init__()`, which
leaves the `Timer` `Task` running, and that causes precompilation
of `PkgB` to hang.

## Example with `expr`
Without Aqua's tests, the developers of `PkgA` might not realize that their
package is essentially unusable with any other package.

## Checking for persistent tasks

Running all of Aqua's tests will automatically check whether your package falls
into this trap. In addition, there are ways to manually run (or tweak) this
specific test.

### Manually running the peristent-tasks check

You can test that an expression using your package finishes without leaving any persistent
tasks by passing a quoted expression:
[`Aqua.test_persistent_tasks(MyPackage)`](@ref) will check whether `MyPackage` blocks
precompilation for any packages that depend on it.

### Using an `expr` to check more than just `__init__`

By default, `Aqua.test_persistent_tasks` only checks whether a package's
`__init__` function leaves persistent tasks running. To check whether other
package functions leave persistent tasks running, pass a quoted expression:

```julia
Aqua.test_persistent_tasks(MyPackage, quote
# Code to run after loading MyPackage
server = MyPackage.start_server()
MyPackage.stop_server!(server)
MyPackage.stop_server!(server) # ideally, this this should cleanly shut everything down. Does it?
end)
```

Expand Down Expand Up @@ -76,8 +102,38 @@ function __init__()
end
```

In more complex cases, you may need to set up independently-callable functions
to launch the tasks and set conditions that allow them to cleanly exit.
In more complex cases, you may need to modify the task to support a clean
shutdown. For example, if you have a `Task` that runs a never-terminating
`while` loop, you could change

```
while true
end
```

to

```
while task_should_run[]
end
```

where

```
const task_should_run = Ref(true)
```

is a global constant in your module. Setting `task_should_run[] = false` from
outside that `while` loop will cause it to terminate on its next iteration,
allowing the `Task` to finish.

## Additional information

[Julia's devdocs](https://docs.julialang.org/en/v1/devdocs/precompile_hang/)
also discuss this issue.

## [Test functions](@id test_persistent_tasks)

Expand Down

2 comments on commit 065f7d7

@lgoettgens
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JuliaRegistrator
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Registration pull request created: JuliaRegistries/General/116999

Tip: Release Notes

Did you know you can add release notes too? Just add markdown formatted text underneath the comment after the text
"Release notes:" and it will be added to the registry PR, and if TagBot is installed it will also be added to the
release that TagBot creates. i.e.

@JuliaRegistrator register

Release notes:

## Breaking changes

- blah

To add them here just re-invoke and the PR will be updated.

Tagging

After the above pull request is merged, it is recommended that a tag is created on this repository for the registered package version.

This will be done automatically if the Julia TagBot GitHub Action is installed, or can be done manually through the github interface, or via:

git tag -a v0.8.8 -m "<description of version>" 065f7d78a67a7a93f956263b3054fa5a0efea70f
git push origin v0.8.8

Please sign in to comment.