# `PhoenixKitAgent.Attachments.Work`
[🔗](https://github.com/BeamLabEU/phoenix_kit_agent/blob/v0.1.0/lib/phoenix_kit_agent/attachments/work.ex#L1)

The scratch space of attachment processing: a private directory tree in the
system's temporary directory (`pk_agent_att/`), where a user's file is copied
to be read and the pages of a scan are rendered.

Everything here is made for one user's data, so:

  * the root and every directory in it are readable by the server's own user
    only (mode `0700`), and a directory's name is random and never reused
    (`File.mkdir/1` fails if it exists), so one run can never pick up
    what an earlier, killed one left behind;
  * the copy of a file is made *inside* such a directory (the destination is
    ours, not a name Storage invents in `/tmp`), so whatever a killed worker
    leaves is under one directory the supervising process removes;
  * a directory that nothing removed (the node was killed, a turn was stopped
    while it was reading a picture) is swept when its age is past the longest
    time a job may take — at start-up and whenever a new one is made.

A worker `adopt/1`s the directory its supervisor made; the directories it
makes itself are then made inside it.

# `adopt`

```elixir
@spec adopt(Path.t()) :: :ok
```

Makes `dir` the place this process's own directories are made in.

# `create`

```elixir
@spec create() :: {:ok, Path.t()} | {:error, :unavailable}
```

A new, empty directory with a random name, `0700`: inside the one this
process `adopt/1`ed, else in the root.

# `fetch`

```elixir
@spec fetch(String.t(), Path.t()) :: {:ok, Path.t()} | {:error, :unreadable}
```

Copies the original of the Storage file `file_uuid` to a new file in `dir`
(readable by this user only) and returns its path.

# `remove`

```elixir
@spec remove(Path.t()) :: :ok
```

Removes `dir` and what is in it.

# `root`

```elixir
@spec root() :: Path.t()
```

The directory every scratch directory is made in.

# `sweep`

```elixir
@spec sweep() :: non_neg_integer()
```

Removes the scratch directories older than the longest a job may take (plus
a margin). Returns how many were removed.

# `with_dir`

```elixir
@spec with_dir((Path.t() -&gt; result)) :: result | {:error, :unreadable}
when result: term()
```

Runs `fun` with a new directory and removes it afterwards; `{:error,
:unreadable}` where there is none to be had.

# `with_file`

```elixir
@spec with_file(String.t(), (Path.t() -&gt; result)) :: result | {:error, :unreadable}
when result: term()
```

Runs `fun` with the path of a copy of the Storage file `file_uuid`, and
removes the copy afterwards. `{:error, :unreadable}` when it cannot be read.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
