# \[ANN\] DiscreteEvents 0.3: discrete event generation and simulation

**URL:** <https://discourse.julialang.org/t/ann-discreteevents-0-3-discrete-event-generation-and-simulation/46477>\
**Category:** Modelling & Simulations\
**Tags:** announcement\
**Created:** [September 11, 2020, 8:53pm UTC](https://discourse.julialang.org/t/ann-discreteevents-0-3-discrete-event-generation-and-simulation/46477 "2020-09-11T20:53:02Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![pbayer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pbayer/32/11675_2.png) [@pbayer](https://discourse.julialang.org/u/pbayer)\
**Post date:** [September 11, 2020, 8:53pm UTC](https://discourse.julialang.org/t/ann-discreteevents-0-3-discrete-event-generation-and-simulation/46477/1 "2020-09-11T20:53:02Z")

</div>

_A Julia package for discrete event generation and simulation_

I’m pleased to announce that [`DiscreteEvents`](https://github.com/pbayer/DiscreteEvents.jl) 0.3 is now available from the Julia registry. It has been renamed from `Simulate` 0.2 following the [discussion on Discourse](https://discourse.julialang.org/t/simulate-v0-2-0-a-julia-package-for-discrete-event-simulation/31822).

DiscreteEvents is an extensive rework and has some exciting features:

- It allows to schedule and execute arbitrary Julia functions and expressions on a clock’s timeline.
- It has a streamlined API allowing to combine several approaches to simulation of discrete event systems (DES): based on events, activities, processes, state-machines and actors.
- It is [well documented](https://pbayer.github.io/DiscreteEvents.jl/dev/) and has a companion site [`DiscreteEventsCompanion`](https://pbayer.github.io/DiscreteEventsCompanion.jl/dev/) with more documentation and examples.
- It is pure Julia and now has much better performance.
- Using Julia’s multi-threading capabilities it introduces _parallel clocks_ (with thread-local time) and allows multi-threaded simulations (experimental!).
- It introduces _real-time clocks_ where you can schedule your functions on a physical timeline (experimental!).

## Example, an M/M/3 queue

Three servers serve customers arriving at an arrival rate λ with a service rate μ. We implement `serve` and `arrive` functions, create a clock and queues, then start three server processes, a Poisson arrival process and run.

```julia
using DiscreteEvents, Printf, Distributions, Random

# describe a server process
function serve(clk::Clock, id::Int, input::Channel, output::Channel, X::Distribution)
    job = take!(input)
    print(clk, @sprintf("%6.3f: server %d serving customer %d\n", tau(clk), id, job))
    delay!(clk, X)
    print(clk, @sprintf("%6.3f: server %d finished serving %d\n", tau(clk), id, job))
    put!(output, job)
end

# model the arrivals
function arrive(c::Clock, input::Channel, cust::Vector{Int})
    cust[1] += 1
    @printf("%6.3f: customer %d arrived\n", tau(c), cust[1])
    put!(input, cust[1])
end

Random.seed!(123) # set random number seed
const μ = 1/3 # service rate
const λ = 0.9 # arrival rate
count = [0] # a job counter

clock = Clock() # create a virtual clock
input = Channel{Int}(Inf)
output = Channel{Int}(Inf)
for i in 1:3 # start three server processes
    process!(clock, Prc(i, serve, i, input, output, Exponential(1/μ)))
end
# create a repeating event for 10 arrivals
event!(clock, fun(arrive, clock, input, count), every, Exponential(1/λ), n=10)
run!(clock, 20) # run the clock 20 time units

```

If we source this program, it runs a simulation.

> **output:**
>
> ```
> 
> julia> include("examples/intro.jl")
> 0.141: customer 1 arrived
> 0.141: server 1 serving customer 1
> 1.668: server 1 finished serving 1
> 2.316: customer 2 arrived
> 2.316: server 2 serving customer 2
> 3.154: customer 3 arrived
> 3.154: server 3 serving customer 3
> 4.182: customer 4 arrived
> 4.182: server 1 serving customer 4
> 4.364: server 3 finished serving 3
> 4.409: customer 5 arrived
> 4.409: server 3 serving customer 5
> 4.533: customer 6 arrived
> 4.566: server 2 finished serving 2
> 4.566: server 2 serving customer 6
> 5.072: customer 7 arrived
> 5.299: server 3 finished serving 5
> 5.299: server 3 serving customer 7
> 5.335: server 1 finished serving 4
> 5.376: customer 8 arrived
> 5.376: server 1 serving customer 8
> 5.833: customer 9 arrived
> 6.134: customer 10 arrived
> 6.570: server 1 finished serving 8
> 6.570: server 1 serving customer 9
> 6.841: server 3 finished serving 7
> 6.841: server 3 serving customer 10
> 8.371: server 2 finished serving 6
> 10.453: server 1 finished serving 9
> 10.477: server 3 finished serving 10
> "run! finished with 40 clock events, 0 sample steps, simulation time: 20.0"
> 
> ```

`DiscreteEvents` is in development and I am happy if you try it out and contribute your ideas, suggestions, experience and code. I think it enters and opens as well some uncharted territory in DES simulation. Maybe some of you are interested to join …

After some time since the last release I now will switch to continuous delivery of updates and improvements.

---

<div class="post-metadata">

**Author:** ![pbayer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pbayer/32/11675_2.png) [@pbayer](https://discourse.julialang.org/u/pbayer)\
**Post date:** [September 16, 2020, 4:03pm UTC](https://discourse.julialang.org/t/ann-discreteevents-0-3-discrete-event-generation-and-simulation/46477/2 "2020-09-16T16:03:35Z")

</div>

Now I’m happy to **announce v0.3.1** of [`DiscreteEvents`](https://github.com/pbayer/DiscreteEvents.jl). It’s available from the Julia registry.

A few days after the last release @hdavid16 contributed some macros and we worked together to create a more Julian API to schedule functions as events or to start them as processes on a clock.

The above example now becomes:

```julia
....

for i in 1:3 # start three server processes
    @process serve(clock, i, input, output, Exponential(1/μ))
end
# create a repeating event for 10 arrivals
@event arrive(clock, input, count) every Exponential(1/λ) 10
@run! clock 20 # run the clock

```

Wouldn’t you like too to schedule and run your functions on a clock as easy as that? 😉
