Verified Commit 4f2c5d01 authored by Raphaël Bleuse's avatar Raphaël Bleuse
Browse files

Remove launcher dependency on functional API

The launcher code is responsible for instantiating the scheduler
requested by the user.
We deport the responsibility of building a subclass of BatsimScheduler
out of the launcher.

For the existing functional API, we introduce a wrapper class emulating
the existing behavior.
parent 4b3436e6
......@@ -662,3 +662,40 @@ def as_scheduler(*args, on_init=[], on_end=[], base_classes=[], **kwargs):
return InheritedScheduler
return convert_to_scheduler
def adapt_functional_scheduler(klass):
"""
Adapt the functional class into a BatsimScheduler subclass.
This is equivalent to retrieving the object returned by klass.__call__
"""
if not issubclass(klass, Scheduler):
raise ValueError(f'{klass} does not implement the functional API.')
class BatsimSchedulerAdapter(BatsimScheduler):
"""Adapter class for the classes implemented with the functional API."""
# the functional scheduler encapsulates the BatsimScheduler, we forward everything there
# this is equivalent to using the object returned by _functional_scheduler.__call__
# this is a dirty hack, but it preserves the functionality of the code
# and simplifies the core logic: it should be rewritten
def __init__(self, options={}):
_functional_scheduler = klass(options)
object.__setattr__(self, '_functional_scheduler', _functional_scheduler)
def __getattribute__(self, attr):
_functional_scheduler = object.__getattribute__(self, '_functional_scheduler')
return getattr(_functional_scheduler._scheduler, attr)
def __setattr__(self, attr, value):
_functional_scheduler = object.__getattribute__(self, '_functional_scheduler')
setattr(_functional_scheduler._scheduler, attr, value)
def __delattr__(self, attr):
_functional_scheduler = object.__getattribute__(self, '_functional_scheduler')
delattr(_functional_scheduler._scheduler, attr, value)
return BatsimSchedulerAdapter
......@@ -8,15 +8,11 @@
import json
import sys
import time
import types
from datetime import timedelta
import importlib.util
import os.path
from pybatsim.batsim.batsim import Batsim, BatsimScheduler, NetworkHandler
from docopt import docopt
import zmq
from pybatsim.batsim.batsim import Batsim
def module_to_class(module):
......@@ -87,14 +83,7 @@ def instanciate_scheduler(name, options):
mod, my_class))
sys.exit(1)
if isinstance(scheduler_non_instancied, types.FunctionType):
from pybatsim.batsim.sched import as_scheduler
scheduler = as_scheduler()(scheduler_non_instancied)
scheduler = scheduler(options)
else:
scheduler = scheduler_non_instancied(options)
if not isinstance(scheduler, BatsimScheduler):
scheduler = scheduler()
scheduler = scheduler_non_instancied(options)
return scheduler
......
......@@ -8,9 +8,10 @@
from pybatsim.batsim.sched.algorithms.backfilling import backfilling_sched
from pybatsim.batsim.sched.algorithms.utils import consecutive_resources_filter
from pybatsim.batsim.sched.scheduler import as_scheduler, adapt_functional_scheduler
def SchedEasySjfBackfill(scheduler):
def _func_SchedEasySjfBackfill(scheduler):
kwargs = {}
kwargs["reservation_depth"] = scheduler.options.get(
......@@ -27,3 +28,10 @@ def SchedEasySjfBackfill(scheduler):
scheduler,
resources_filter=consecutive_resources_filter,
**kwargs)
SchedEasySjfBackfill = adapt_functional_scheduler(
as_scheduler()(
_func_SchedEasySjfBackfill
)
)
......@@ -8,10 +8,18 @@
from pybatsim.batsim.sched.algorithms.filling import filler_sched
from pybatsim.batsim.sched.algorithms.utils import consecutive_resources_filter
from pybatsim.batsim.sched.scheduler import as_scheduler, adapt_functional_scheduler
def SchedFcfs(scheduler):
def _func_SchedFcfs(scheduler):
return filler_sched(
scheduler,
resources_filter=consecutive_resources_filter,
abort_on_first_nonfitting=True)
SchedFcfs = adapt_functional_scheduler(
as_scheduler()(
_func_SchedFcfs
)
)
......@@ -8,10 +8,18 @@
from pybatsim.batsim.sched.algorithms.filling import filler_sched
from pybatsim.batsim.sched.algorithms.utils import consecutive_resources_filter
from pybatsim.batsim.sched.scheduler import as_scheduler, adapt_functional_scheduler
def SchedFiller(scheduler):
def _func_SchedFiller(scheduler):
return filler_sched(
scheduler,
resources_filter=consecutive_resources_filter,
abort_on_first_nonfitting=False)
SchedFiller = adapt_functional_scheduler(
as_scheduler()(
_func_SchedFiller
)
)
......@@ -7,12 +7,12 @@
"""
from pybatsim.batsim.sched import Scheduler
from pybatsim.batsim.sched.algorithms.filling import filler_sched
from pybatsim.batsim.sched.algorithms.utils import consecutive_resources_filter
from pybatsim.batsim.sched.scheduler import Scheduler, adapt_functional_scheduler
class SchedSendRecv(Scheduler):
class _func_SchedSendRecv(Scheduler):
def on_job_message(self, job, message):
if message.type == "accept":
......@@ -25,3 +25,6 @@ class SchedSendRecv(Scheduler):
self,
resources_filter=consecutive_resources_filter,
abort_on_first_nonfitting=False)
SchedSendRecv = adapt_functional_scheduler(_func_SchedSendRecv)
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment