Giter VIP home page Giter VIP logo

Comments (7)

hdavid16 avatar hdavid16 commented on June 16, 2024 1

Hi @BenLauwens , it's been over a year... Any update? I wouldn't want this great package to die away...

from concurrentsim.jl.

hdavid16 avatar hdavid16 commented on June 16, 2024 1

I think we should get preemption back into SimJulia. Preemption is a fundamental element in queueing systems. Please restore this or give us some guidance on how to do it.

from concurrentsim.jl.

BenLauwens avatar BenLauwens commented on June 16, 2024

Hi

Preemption is no longer supported. Some users complained that my implementation was not what they really wanted. So I left it out.
I will add an example to the documentation detailing how this can be implemented.
Kind regards

Ben

from concurrentsim.jl.

hdavid16 avatar hdavid16 commented on June 16, 2024

@BenLauwens , have you had a chance to add the documentation for implementing preemption?

from concurrentsim.jl.

hdavid16 avatar hdavid16 commented on June 16, 2024

If anybody is interested. This can be accomplished with something along the lines:

Preemption can be done on a Store object if an item of higher priority arrives. The amount of time the preempted object was served is stored.

This change adds a method to put that requires that the item have the following fields:

  • :priority::Int: Integer specifying the priority of that item (the more negative, the higher the priority).
  • :process::Process: The storage process of the item. This is used to know which Process to interrupt when preempting.

To do this, define the following method for put:

"""
  put(sto::Store{T}, item::T, preempt::Bool=false,
        filter::Function=get_any_item) where T
Put an `item` in a `Store` and allow for preemption using `filter` to select
  which item to remove from the `Store` when preempting.
This method requires that T be a mutable struct with the fields:
- `:priority::Int`: Integer specifying the priority of that `item` (the more
  negative, the higher the priority).
- `:process::Process`: Storage `Process` for the `item`. Used to know which
  `Process` to interrupt when preempting.
"""
function put(sto::Store{T}, item::T, preempt::Bool=false, filter::Function=get_any_item) where T
    @assert :priority in fieldnames(T) "Preemption requires that the item being stored have :priority as one of its fields."
    @assert :process in fieldnames(T) && item.process isa Process "Preemption requires that the item being stored have `:process` as one of its fields."
    if preempt && !isempty(sto.items) && item.priority < maximum([itm.priority for itm in sto.items]) #if the new item priority is higher than the priority of at least one of the items in the store, preempt
        #remove item from store
        stoitems = [itm for itm in sto.items] #original items in sto
        get(sto, filter) #get item from store
        pitem = setdiff(stoitems, [itm for itm in sto.items])[1] #find removed item
        proc = pitem.process #process to interrupt
        interrupt(proc, item) #interrupt process on removed item identify item causing the preemption
    end
    #put new item into the queue
    put(sto, item, priority = item.priority)
end

The following serves as an example of how to implement preemption:

using ResumableFunctions, SimJulia

#Define Job (item) to send to the queue (Store)
abstract type AbstractJob end
mutable struct Job <: AbstractJob
    id::Int
    arrival::Number
    priority::Int
    start_service::Number
    time_in_service::Number
    process::Union{Missing, SimJulia.Process}
    size::Number
end

#define a function to serve jobs that arrive at a queue and allow preemption
@resumable function serve(env, server, job)
    @yield timeout(env, job.arrival) #job arrives
    println("job $(job.id) enters queue at t = $(now(env))")
    while true
        try
            @yield put(server, job, true) #add job to queue, allow preemption
            println("Starting service on job $(job.id) at t = $(now(env)).")
            job.start_service = now(env) #save time service started on job
            @yield timeout(env, job.size - job.time_in_service) #service duration excludes any time already spent in service (if preempted)
            println("Service complete on job $(job.id) at t = $(now(env)).")
            job.time_in_service = now(env) - job.start_service #update time in serice
            get(server, x -> x.id == job.id) #remove job from queue
            break
        catch exc
            pre = exc.cause #find cause of preemption
            job.time_in_service = now(env) - job.start_service #update time in service
            println("Service on job $(job.id) interrupted (preempted) by job $(pre.id) at t = $(now(env)).")
        end
    end
end

#create simulation
sim = Simulation() #simulation object
server = Store{Job}(sim, capacity = UInt(1)) #server that processes jobs
#add 3 jobs with priorities -1, 0, -2 arriving at times 0, 1, 2
job1 = Job(1,0,-1,0,0,missing,3) 
job2 = Job(2,1,0,0,0,missing,3)
job3 = Job(3,2,-2,0,0,missing,3)

#create and store service processes
job1.process = @process serve(sim, server, job1)
job2.process = @process serve(sim, server, job2)
job3.process = @process serve(sim, server, job3)

#run simulation
run(sim)

#output
#=
job 1 enters queue at t = 0.0
Starting service on job 1 at t = 0.0.
job 2 enters queue at t = 1.0
job 3 enters queue at t = 2.0
Service on job 1 interrupted (preempted) by job 3 at t = 2.0.
Starting service on job 3 at t = 2.0.
Service complete on job 3 at t = 5.0.
Starting service on job 1 at t = 5.0.
Service complete on job 1 at t = 6.0.
Starting service on job 2 at t = 6.0.
Service complete on job 2 at t = 9.0.
=#

from concurrentsim.jl.

BenLauwens avatar BenLauwens commented on June 16, 2024

Hi

The problem with preemption is that depending on the use-case a preempted event can be resumed with a remaining time (as in the post) but it can also be possible that the event has to be restarted (or rescheduled) completely (e.g. a data packet in a wireless network) or that the "service time" depends on other processes and no direct comparison between the old service and the new service can be made.
I am aware that Docs are missing but other projects are more important. This does not mean that SimJulia is left behind but for the moment only bug fixing will be done.
Kind regards

Ben

from concurrentsim.jl.

hdavid16 avatar hdavid16 commented on June 16, 2024

It would be good to add something in this regard to the Docs.
While the package may not be planned to receive any upgrades besides bug fixing, it would be very helpful to get the documentation up to speed.

from concurrentsim.jl.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.