hi juri,

vetoJobExecution is fine for me as well.
Class<?> as param-type is fine. (if custom logic needs to be string-based,
users can always use Class#getName.)
you don't need ExecutionContext with the suggested spi - it was just a hint
that you can use it already (with existing versions of ds) to reach the
same.
(so the new spi is mainly for convenience - since it's a common use-case...)

regards,
gerhard

Am Do., 21. Feb. 2019 um 10:52 Uhr schrieb Juri Berlanda <
[email protected]>:

> Hi all,
>
> sure thing, will change to optional lookup as soon as I have some spare
> time.
>
> Then there is still the question on the shouldJobBeStarted(Class<?>)
> method:
>
>   * I find the name clumsy and far from self-explanatory
>       o do you agree, that an vetoJobExecution (with inversed logic)
>         similar to Quartz' Listener would be better?
>   * Class<?> as parameter might not be the best choice
>       o Change to String className?
>       o Introduce a POJO, which includes both and let the user choose?
>       o Quartz' ExecutionContext looks nice, though I would avoid that,
>         since it introduces a fully fledged dependency to Quartz.
>
> Cheers,
>
> Juri
>
> On 2/21/19 9:41 AM, Gerhard Petracek wrote:
> > hi juri,
> >
> > esp. with weld it's easier to provide just an interface + an optional
> > lookup (if there is no real default-implementation).
> > so you don't need to use global alternatives.
> >
> > @the rest:
> > you answered it yourself actually.
> > -> imo the change to the optional lookup should be enough.
> >
> > regards,
> > gerhard
> >
> >
> >
> > Am Fr., 15. Feb. 2019 um 17:31 Uhr schrieb Juri Berlanda <
> > [email protected]>:
> >
> >> Hi all,
> >>
> >> I see the point with API and SPI, moved the interface to SPI package.
> >>
> >> Regarding the optional lookup: because of shouldJobBeStarted(Class<?>)
> >> is needed in AbstractJobAdapter<T> - and I have @Inject available at
> >> that point, so I went with a default implementation and @Inject it,
> >> rather then doing an optional lookup via BeanManager. I also think it
> >> makes the code cleaner, as I can omit the null checks. Finally, I think
> >> in pretty much all use cases I can think of one would only override at
> >> most one of the methods, as a either of:
> >>
> >>    * scheduler is enabled and so is every job (current and default
> behavior)
> >>    * scheduler is enabled, but I want to control individual jobs
> >>    * scheduler is disabled
> >>
> >> so why would one have to always implement both? Though, this need could
> >> be worked around using Java8's default on the SchedulerControl
> interface.
> >>
> >> On the other hand, I agree that overriding the default implementation as
> >> I now have it introduces a a compile-time dependency to
> >> deltaspike-scheduler-module-impl, and I can see how one would like to
> >> avoid that.
> >>
> >> As another possibility I could make what currently is the interface the
> >> default @ApplicationScoped implementation, though that might make it
> >> less intuitive, that SchedulerControl this is a thingy meant to be
> >> overridden.
> >>
> >> In the end, all of this is just expresses my personal taste, so if any
> >> of it blocks a potential merge I'm more then happy to throw it
> overboard.
> >>
> >> Cheers,
> >>
> >> Juri
> >>
> >> On 2/9/19 1:53 PM, Gerhard Petracek wrote:
> >>> hi juri,
> >>>
> >>> i haven't done a full review, however, your approach via
> >> JobRunnableAdapter
> >>> looks fine.
> >>> with an optional lookup, you would even get rid of the default
> >>> implementation.
> >>> (+ imo it's a spi and not an api)
> >>>
> >>> for different requirements (in >different< projects) we did all 3
> >>> approaches mentioned in this thread (and even some "hybrid" approaches
> >> e.g.
> >>> based on apache ignite).
> >>> that was one of the reasons for adding
> >>> SchedulerBaseConfig.JobCustomization.RUNNABLE_ADAPTER_CLASS_NAME.
> >>>
> >>> quite soon i'll summarize and share an approach i (and several others)
> >> did
> >>> over and over the past few years.
> >>> in 2017 i suggested to add a simple abstraction for it (to ds),
> however,
> >>> maybe we can reach an agreement this time...
> >>>
> >>> regards,
> >>> gerhard
> >>>
> >>>
> >>> Am Sa., 9. Feb. 2019 um 11:10 Uhr schrieb Juri Berlanda <
> >>> [email protected]>:
> >>>
> >>>> Hi all,
> >>>>
> >>>> I created an issue at
> >>>> https://issues.apache.org/jira/browse/DELTASPIKE-1369. I already
> have a
> >>>> working prototype, though code polishing is still needed.
> >>>>
> >>>> @gerhard: I didn't know about the Listeners in Quartz, but I agree:
> what
> >>>> I propose is pretty much another way of doing
> >>>> TriggerListener.vetoJobExecution(Trigger trigger, JobExecutionContext
> >>>> context). But I guess (please correct me if I'm wrong) these Listeners
> >>>> cannot use Injection (except via BeanProvider, BeanManager and stuff
> >>>> like that). My approach - being a CDI Bean - would provide support for
> >>>> @Inject out of the box for any customizing bean.
> >>>>
> >>>> In addition, the Listeners seem to not provide a mechanism to prevent
> >>>> the scheduler from starting all together (see my initial use case in
> the
> >>>> first mail of this thread).
> >>>>
> >>>> I propose we move the discussion to the Jira issue. I also have listed
> >>>> some minor points I'd like your feedback on.
> >>>>
> >>>> Cheers,
> >>>>
> >>>> Juri
> >>>> ||||
> >>>>
> >>>> On 2/4/19 9:29 PM, Gerhard Petracek wrote:
> >>>>> hi @ all,
> >>>>>
> >>>>> limiting it to the scheduler-module is possible - but if it is the
> only
> >>>>> use-case, it wouldn't be needed, because it's easier to use
> >>>>> Scheduler#unwrap to register your own TriggerListener via
> >>>>> #getListenerManager. in the end such use-cases are the reason for
> >>>>> Scheduler#unwrap.
> >>>>>
> >>>>> regards,
> >>>>> gerhard
> >>>>>
> >>>>>
> >>>>>
> >>>>> Am Mo., 4. Feb. 2019 um 17:26 Uhr schrieb Mark Struberg
> >>>>> <[email protected]>:
> >>>>>
> >>>>>> doesn't sound wrong - actually sounds really fine ;)
> >>>>>>
> >>>>>> Do you probably want to provide a ticket and patch?
> >>>>>>
> >>>>>> LieGrue,
> >>>>>> strub
> >>>>>>
> >>>>>>> Am 04.02.2019 um 14:19 schrieb Juri Berlanda <
> >>>> [email protected]
> >>>>>>> :
> >>>>>>>
> >>>>>>> Hi,
> >>>>>>>
> >>>>>>> I still think it would be nice to just have a simple mechanism
> >> telling
> >>>>>> "Just don't start here".
> >>>>>>> I'm sceptic on a.) and b.) because they would introduce a database
> >>>>>> binding to DeltaSpike, which I think may make it hard to use in some
> >>>> stacks
> >>>>>> (think projects running on NoSQL databases). In addition, I think
> >>>> something
> >>>>>> similar as you proposed in a.) can already be achieved by running
> >>>> Quartz in
> >>>>>> ClusteredMode, though I never tried that.
> >>>>>>> What I would propose is some pluggable Bean (via Alternative,
> >>>>>> Specializes or stuff like that) with 2 functions:
> >>>>>>> boolean isSchedulerEnabled();
> >>>>>>>
> >>>>>>> boolean shouldJobBeStarted(Class<T>);
> >>>>>>>
> >>>>>>> The default implementation would return true on both. Any
> Alternative
> >>>>>> could then return false on isSchedulerEnabled() to fully disable it
> >>>>>> (lowering overall overhead in a scenario as mine), or do something
> >>>> smart in
> >>>>>> shouldJobBeStarted() to determine at Runtime whether a specific Job
> >>>> should
> >>>>>> be ran on the current node (should accomodate for your usecase).
> >>>>>>> What do you think?
> >>>>>>>
> >>>>>>> Cheers,
> >>>>>>>
> >>>>>>> Juri
> >>>>>>>
> >>>>>>> On 1/30/19 9:13 AM, Mark Struberg wrote:
> >>>>>>>> Hi folks!
> >>>>>>>>
> >>>>>>>> Yes, that solution works.
> >>>>>>>>
> >>>>>>>> I had the same problem (multiple nodes, code should only run
> once).
> >>>>>>>> Pinning to one cluster node is a possible solution, but if that
> one
> >>>>>> node is down then the processing stops.
> >>>>>>>> I went for another solution. I wrote some Interceptor which
> >> basically
> >>>>>> guards against a central DB.
> >>>>>>>> There are 2 different strategies:
> >>>>>>>> a.) Keep an pesimistic lock on a row in a DB. One row per Class or
> >>>>>> locking key. (DB must support row locking).
> >>>>>>>>     Pro: easy to implement. Most work is done by the database
> >>>>>>>>     Con: If the whole thread gets stuck then you're in back luck.
> >> One is
> >>>>>> also bound to the maximum transaction timeout.
> >>>>>>>>      So if you want to have a task running for one hour (doing
> e.g.
> >>>>>> multiple transaction batches) you cannot use this strategy.
> >>>>>>>> b.) Have a 'watchdog' table which remembers the node and whether
> >>>>>> active. 2 Minutes not updated means that the task blew up and
> another
> >>>> node
> >>>>>> might take up.
> >>>>>>>>     Pro: sufficiently easy to implement. A background thread which
> >> is a
> >>>>>> watchdog and uipdates the 'lastActive' timestamp in the DB in the
> >>>>>> background.
> >>>>>>>>     Con: It takes a while for another node to pick up the work.
> >> Minimum
> >>>> 2
> >>>>>> minutes. We also need a clear 'nodeId'. That might be the IP, but if
> >>>>>> multiple JVMs run on the same box then you need some custom
> >> identifier.
> >>>> The
> >>>>>> JVM id would be a candidate as it is unique. Otoh a restart would
> >> mean 2
> >>>>>> minutes pause.
> >>>>>>>> c.) no database at all but network based locking. Might be easier
> or
> >>>>>> harder to setup depending on your infrastructure and security
> >> measures.
> >>>>>>>> Should we implement any of these in DeltaSpike?
> >>>>>>>> Which one makes more sense?
> >>>>>>>> (I personally went for option b for my use cases)
> >>>>>>>>
> >>>>>>>> LieGrue,
> >>>>>>>> strub
> >>>>>>>>
> >>>>>>>>
> >>>>>>>>> Am 28.01.2019 um 13:28 schrieb Juri Berlanda <
> >>>>>> [email protected]>:
> >>>>>>>>> Hi,
> >>>>>>>>>
> >>>>>>>>> just for completeness sake: I was able to achieve what I wanted
> >> using
> >>>>>> a custom config source. I presume this is not how it is supposed to
> >> be,
> >>>> but
> >>>>>> it works:
> >>>>>>>>> public class SchedulerConfigSource implements ConfigSource {
> >>>>>>>>>        private static final String CLASS_DEACTIVATOR_KEY =
> >>>>>> "org.apache.deltaspike.core.spi.activation.ClassDeactivator";
> >>>>>>>>>        private static final String CLASS_DEACTIVATOR_VALUE =
> >>>>>>
> "org.apache.deltaspike.core.impl.activation.DefaultClassDeactivator";
> >>>>>>>>>        private static final String SCHEDULER_DISABLED_KEY =
> >>>>>>
> "deactivate.org.apache.deltaspike.scheduler.impl.SchedulerExtension";
> >>>>>>>>>        private final int ordinal;
> >>>>>>>>>
> >>>>>>>>>        SchedulerConfigSource(int ordinal) {
> >>>>>>>>>            this.ordinal = ordinal;
> >>>>>>>>>        }
> >>>>>>>>>
> >>>>>>>>>        @Override
> >>>>>>>>>        public int getOrdinal() {
> >>>>>>>>>            return ordinal;
> >>>>>>>>>        }
> >>>>>>>>>
> >>>>>>>>>        @Override
> >>>>>>>>>        public Map<String, String> getProperties() {
> >>>>>>>>>            return Stream.of(CLASS_DEACTIVATOR_KEY,
> >>>> SCHEDULER_DISABLED_KEY)
> >>>>>>>>>                    .collect(Collectors.toMap(Function.identity(),
> >>>>>> this::getPropertyValue));
> >>>>>>>>>        }
> >>>>>>>>>
> >>>>>>>>>        @Override
> >>>>>>>>>        public String getPropertyValue(String key) {
> >>>>>>>>>            if (CLASS_DEACTIVATOR_KEY.equals(key))
> >>>>>>>>>                return CLASS_DEACTIVATOR_VALUE;
> >>>>>>>>>            if (SCHEDULER_DISABLED_KEY.equals(key))
> >>>>>>>>>                return Boolean.toString(!isSchedulerNode());
> >>>>>>>>>            return null;
> >>>>>>>>>        }
> >>>>>>>>>
> >>>>>>>>>        private boolean isSchedulerNode() {
> >>>>>>>>>            // Evaluate the condition here
> >>>>>>>>>        }
> >>>>>>>>>
> >>>>>>>>>        @Override
> >>>>>>>>>        public String getConfigName() {
> >>>>>>>>>            return "SchedulerConfigSource";
> >>>>>>>>>        }
> >>>>>>>>>
> >>>>>>>>>        @Override
> >>>>>>>>>        public boolean isScannable() {
> >>>>>>>>>            return false;
> >>>>>>>>>        }
> >>>>>>>>> }
> >>>>>>>>>
> >>>>>>>>> Thought I may as well add it if somebody else. And don't forget
> to
> >>>>>> register the ConfigSource.
> >>>>>>>>> I presume there is a better way to achieve this. If you know of
> >> one,
> >>>>>> please let me know.
> >>>>>>>>> Cheers,
> >>>>>>>>>
> >>>>>>>>> Juri
> >>>>>>>>>
> >>>>>>>>> On 1/25/19 3:56 PM, Juri Berlanda wrote:
> >>>>>>>>>> I was able to achieve similar with Deltaspike's own Deactivable.
> >> It
> >>>>>> does work, i.e. I can set:
> >>
> org.apache.deltaspike.core.spi.activation.ClassDeactivator=org.apache.deltaspike.core.impl.activation.DefaultClassDeactivator
> >> deactivate.org.apache.deltaspike.scheduler.impl.SchedulerExtension=true
> >>>>>>>>>> in my configs, and Scheduler stays off. But - as mentioned - I
> >> need
> >>>>>> this to be evaluated on system startup, not at Config level. So I
> >> tried
> >>>>>> implementing my own SchedulerExtension like:
> >>>>>>>>>> public class MySchedulerExtension extends SchedulerExtension {
> >>>>>>>>>>        @Override
> >>>>>>>>>>        protected void init(@Observes BeforeBeanDiscovery
> >>>>>> beforeBeanDiscovery) {
> >>>>>>>>>>            if (isSchedulerNode())
> >>>>>>>>>>                super.init(beforeBeanDiscovery);
> >>>>>>>>>>        }
> >>>>>>>>>> }
> >>>>>>>>>>
> >>>>>>>>>> I can register it via SPI and from the logs I see it is indeed
> >>>>>> initialized, while SchedulerExtension is not. Victory, right? Not
> >>>> quite...
> >>>>>>>>>> I am testing this with OpenWebbeans 2.0.6., and I face the
> >> problem,
> >>>>>> that CDI now complains about ambiguous Bean for SchedulerExtension
> in
> >>>>>> SchedulerProducer (which I can see where that comes from), but I am
> >> just
> >>>>>> not able to exclude SchedulerProducer - I wouldn't even need it. I
> >> tried
> >>>>>> various combinations of @Specialize, @Alternative and <scan><exclude
> >>>>>> .../></scan>, but none of them seem to work. I guess the reason for
> it
> >>>> is
> >>>>>> the CDI 1.0 beans.xml in scheduler-impl? Can anybody confirm? Would
> it
> >>>> be
> >>>>>> possible to move higher - 1.1 at least for getting support for
> >>>>>> <scan><exclude .../></scan>?
> >>>>>>>>>> This leads me to the assumption, that scheduler-impl's
> >>>>>> SchedulerExtension is just not extensible at the moment. Or did
> >> anybody
> >>>>>> succeed in such an endeavor?
> >>>>>>>>>> Since I do not want to patch the implementation, my next guess
> is
> >> to
> >>>>>> implement a custom ConfigSource, which evaluates isSchedulerNode()
> and
> >>>> sets
> >>>>>> deactivate.org.apache.deltaspike.scheduler.impl.SchedulerExtension
> >>>>>> accordingly. Does that make sense?
> >>>>>>>>>> Kind regards,
> >>>>>>>>>>
> >>>>>>>>>> Juri
> >>>>>>>>>>
> >>>>>>>>>> On 1/24/19 9:04 PM, Alex Roytman wrote:
> >>>>>>>>>>> in my case i need to be able to turn it on/off on demand and I
> >> only
> >>>>>> have
> >>>>>>>>>>> couple of daily tasks so for me it was good enough
> >>>>>>>>>>> If if you just need to do it on startup by node type you could
> >> bind
> >>>>>> it to a
> >>>>>>>>>>> property
> >>>>>>>>>>> @Scheduled(cronExpression = "{reindex.schedule}")
> >>>>>>>>>>> public class ReindexTask implements org.quartz.Job {
> >>>>>>>>>>> ...
> >>>>>>>>>>> and that property could probably be a cron expression which
> never
> >>>>>> fire on
> >>>>>>>>>>> all of your nodes but the scheduler
> >>>>>>>>>>> not nice but the whole thing is rather static - admittedly i
> did
> >>>> not
> >>>>>> dig
> >>>>>>>>>>> very deep
> >>>>>>>>>>>
> >>>>>>>>>>>
> >>>>>>>>>>> On Thu, Jan 24, 2019 at 2:44 PM Juri Berlanda <
> >>>>>> [email protected]>
> >>>>>>>>>>> wrote:
> >>>>>>>>>>>
> >>>>>>>>>>>> Thanks for the quick reply. I thought about that, but I don't
> >> like
> >>>>>> this
> >>>>>>>>>>>> solution, since it involves to much boilerplate for my taste.
> In
> >>>>>>>>>>>> addition, I find it cumbersome having to add these 2 lines in
> >>>> every
> >>>>>>>>>>>> single task. I also thought about having an abstract base
> class
> >>>> for
> >>>>>> this
> >>>>>>>>>>>> purpose, but I'm not happy with the solution...
> >>>>>>>>>>>>
> >>>>>>>>>>>> In short: I hoped for a cleaner solution.
> >>>>>>>>>>>>
> >>>>>>>>>>>> On 1/24/19 7:03 PM, Alex Roytman wrote:
> >>>>>>>>>>>>> Let the scheduler run and execute your task  but inside of
> the
> >>>> task
> >>>>>>>>>>>> itself
> >>>>>>>>>>>>> check if you want to execute your logic or short circuit it
> to
> >>>>>> noop.
> >>>>>>>>>>>> Since
> >>>>>>>>>>>>> you do not run it often should not be an overhead and it will
> >> let
> >>>>>> you
> >>>>>>>>>>>> fail
> >>>>>>>>>>>>> over for any mode to execute it as long as you have a
> mechanism
> >>>> to
> >>>>>> lock
> >>>>>>>>>>>> on
> >>>>>>>>>>>>> something and record execution result to avoid simultaneous
> >>>>>> execution or
> >>>>>>>>>>>>> double exexution
> >>>>>>>>>>>>>
> >>>>>>>>>>>>> On Thu, Jan 24, 2019, 12:37 PM Juri Berlanda <
> >>>>>> [email protected]
> >>>>>>>>>>>>> wrote:
> >>>>>>>>>>>>>
> >>>>>>>>>>>>>> Hi,
> >>>>>>>>>>>>>>
> >>>>>>>>>>>>>> I am currently trying to implement scheduled jobs using
> >>>>>> DeltaSpike's
> >>>>>>>>>>>>>> Scheduler module, and I really like how little boilerplate I
> >>>> need
> >>>>>> for
> >>>>>>>>>>>>>> getting it up and running.
> >>>>>>>>>>>>>>
> >>>>>>>>>>>>>> Our application runs on multiple nodes, but the tasks are
> very
> >>>>>>>>>>>>>> inexpensive, run only once a day, and I don't need failover
> -
> >> if
> >>>>>> they
> >>>>>>>>>>>>>> fail once, and succeed the day after its totally fine.
> >> Therefore
> >>>>>> I'd
> >>>>>>>>>>>>>> like to avoid setting up Quartz in clustered mode. But I
> still
> >>>>>> want the
> >>>>>>>>>>>>>> Jobs to only run once. So my idea was to restrict the
> >> execution
> >>>>>> of the
> >>>>>>>>>>>>>> jobs to a single scheduler node.
> >>>>>>>>>>>>>>
> >>>>>>>>>>>>>> So my question is: Is it possible to somehow hook into the
> >>>>>> Scheduler
> >>>>>>>>>>>>>> module to say something like:
> >>>>>>>>>>>>>>
> >>>>>>>>>>>>>> if (isSchedulerNode())
> >>>>>>>>>>>>>>         startScheduler();
> >>>>>>>>>>>>>> else
> >>>>>>>>>>>>>>         doNothing();
> >>>>>>>>>>>>>>
> >>>>>>>>>>>>>> It would be perfect if said isSchedulerNode() could be
> >> evaluated
> >>>>>> on
> >>>>>>>>>>>>>> system startup (e.g. acquire a distributed lock) and would
> not
> >>>>>> rely on
> >>>>>>>>>>>>>> static values (e.g. config files, environment variables,
> >> etc.).
> >>>>>>>>>>>>>> I can see how this is a bad idea in general (no
> >> load-balancing,
> >>>> no
> >>>>>>>>>>>>>> failover) and I do have some ideas on how I would implement
> >>>> that.
> >>>>>> But
> >>>>>>>>>>>>>> for these jobs I just don't care about any of this, so I'd
> >> like
> >>>>>> to avoid
> >>>>>>>>>>>>>> having to set up a whole lot of infrastructure around my
> >>>>>> application
> >>>>>>>>>>>>>> just to see this working.
> >>>>>>>>>>>>>>
> >>>>>>>>>>>>>> Is there a possibility to achieve this without patching
> >>>>>>>>>>>>>> deltaspike-scheduler-module-impl?
> >>>>>>>>>>>>>>
> >>>>>>>>>>>>>> Kind regards,
> >>>>>>>>>>>>>>
> >>>>>>>>>>>>>> Juri
> >>>>>>>>>>>>>>
> >>>>>>>>>>>>>>
>

Reply via email to