<commit_before># An Overview of Concurrently

The [README][] already introduced the basic interface of Concurrently. 
This document explores the underlying concepts and explains how all parts work
together. For even more details and examples about a specific topic follow the
interspersed links to the [API documentation][].

Let's start with the concept of an *evaluation*.


## Evaluations

An evaluation is an independent execution context. It is similar to a thread or
a fiber since it can be suspended and resumed independently from other
evaluations.

Every ruby program already has an implicit [root evaluation][Concurrently::Evaluation]
running. Unless you explicitly tell your program to evaluate code concurrently
it is evaluated in the root evaluation. The root evaluation runs as long as
your program is running. Thus it is never concluded and its result cannot be
awaited.

Evaluating code with `concurrently(&block)` is done in its own type of
[evaluation][Concurrently::Proc::Evaluation]. Contrary to the root evaluation,
this evaluation has an end with a result. Next to its similarity to a thread
resp. fiber it is also similar to a future or a promise. It provides access
to its (future) result and offers the ability to shortcut its execution by
manually injecting a result. Once the evaluation has a result it is *concluded*.

```ruby
# This is the root evaluation

concurrently do
  # This is a concurrent evaluation
end

concurrently do
  # This is another concurrent evaluation
end
```

## Concurrent Evaluation of Code

Evaluating a piece of code concurrently involves three distinct phases:

                   1)     2)     3)
    evaluation0 ---+-------------+--->
                   |             |
    evaluation1    `-------------´

1) Invocation: evaluation0 creates a separate execution context evaluation1 to
   evaluate the code in. It does not wait for evaluation1 to finish.
2) Asynchronicity: evaluation0 and evaluation1 run independently from each
   other. evaluation0 does not know whether evaluation1 has finished or not.
3) Synchronization: If evaluation0 needs the result of evaluation1 it has to
   wait for it. This synchronizes evaluation1 with evaluation0 again. If
   evaluation1 has not finished yet evaluation0 blocks until it has.

Every tool Concurrently offers is linked to one of these phases.


### Invocation

To start evaluating code concurrently use [Kernel#concurrently][]:

```ruby
evaluation = concurrently do
  # code to run concurrently
end
```

It returns immediately with a handle to the started evaluation. The evaluation
will be processed in the background.

[Kernel#concurrently][] is actually a shortcut for
<commit_msg>improved documentating the phases of concurrent evaluations<commit_after># An Overview of Concurrently

The [README][] already introduced the basic interface of Concurrently. 
This document explores the underlying concepts and explains how all parts work
together. For even more details and examples about a specific topic follow the
interspersed links to the [API documentation][].

Let's start with the concept of an *evaluation*.


## Evaluations

An evaluation is an independent execution context. It is similar to a thread or
a fiber since it can be suspended and resumed independently from other
evaluations.

Every ruby program already has an implicit [root evaluation][Concurrently::Evaluation]
running. Unless you explicitly tell your program to evaluate code concurrently
it is evaluated in the root evaluation. The root evaluation runs as long as
your program is running. Thus it is never concluded and its result cannot be
awaited.

Evaluating code with `concurrently(&block)` is done in its own type of
[evaluation][Concurrently::Proc::Evaluation]. Contrary to the root evaluation,
this evaluation has an end with a result. Next to its similarity to a thread
resp. fiber it is also similar to a future or a promise. It provides access
to its (future) result and offers the ability to shortcut its execution by
manually injecting a result. Once the evaluation has a result it is *concluded*.

```ruby
# This is the root evaluation

concurrently do
  # This is a concurrent evaluation
end

concurrently do
  # This is another concurrent evaluation
end
```


## Concurrent Evaluation of Code

Evaluating a piece of code concurrently involves three distinct phases:

                   1      2      3
    evaluation0 ---+-------------+--->
                   |             |
    evaluation1    `--+-----+----´
                      |     |
                      t     io

1. Invocation: evaluation0 kicks off evaluation1 to process the code in. It
   does it asynchronously by not waiting for evaluation1 to finish.
2. Computation: evaluation0 and evaluation1 run independently from each
   other. evaluation1 synchronizes itself with other events (e.g. with time or
   I/O).
3. Synchronization: If evaluation0 is interested in the result of evaluation1
   it has to wait for it. This synchronizes evaluation1 with evaluation0 again.
   If evaluation1 has not finished yet evaluation0 blocks until it has.

Every tool Concurrently offers is linked to one of these phases.


### Invocation

To start evaluating code concurrently use [Kernel#concurrently][]:

```ruby
evaluation = concurrently do
  # code to run concurrently
end
```

It returns immediately with a handle to the started evaluation. The evaluation
will be processed in the background.

[Kernel#concurrently][] is actually a shortcut for

{'fraction_non_alphanumeric': 0.05490909090909091, 'fraction_numerical': 0.007454545454545454, 'mean_word_length': 3.6697792869269947, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5787318', 'n_tokens_mistral': 1355, 'n_tokens_neox': 1257, 'n_words': 755}