How can I create a background job in AEM as a Cloud?

Avatar

Avatar

watopin

Avatar

watopin

watopin

19-03-2021

I tried 2 ways to do a periodical background job.
 

1:sling job. This was executed on both local SDK and AEM cloud, but executed many times when the specified time come.

2:commons scheduler. This is good on a local SDK, but this did nothing on AEM cloud environment.

 

So I'm stuck.

Either way, How can I do a precise background job?

 

Here is my sample code1 : sling jobs way(service and consumer).executed many times when the specified time come.

 

import org.apache.sling.event.jobs.JobManager;
import org.apache.sling.event.jobs.JobBuilder.ScheduleBuilder;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Component
public class MyJobService {
    private static final Logger logger = LoggerFactory.getLogger(MyJobService.class);
    
    @reference
    private JobManager jobManager;

    public static final String JOB_TOPIC = "my/sample/jobtopic";
    @activate
    public void startScheduledJob() {
        ScheduleBuilder scheduleBuilder = jobManager.createJob(JOB_TOPIC).schedule();
       
        scheduleBuilder.hourly(9, 0); // execute daily at AM9:00
        if (scheduleBuilder.add() == null) {
            logger.error("myjobservice error");
        }
    }
}
import org.apache.sling.event.jobs.Job;
import org.apache.sling.event.jobs.consumer.JobConsumer;
import org.osgi.service.component.annotations.Component;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Component(
    immediate = true,
    service = JobConsumer.class,
    property = {
        JobConsumer.PROPERTY_TOPICS + "=my/sample/jobtopic"
    }
)
public class MyJobConsumer implements JobConsumer {
    private static final Logger logger = LoggerFactory.getLogger(MyJobConsumer.class);
    @Override
    public JobResult process(Job job) {
        String topic = job.getTopic();
        logger.info("this message is from myjobconsumer. topic is " + topic);
        return JobResult.OK;
    }  
}

 

 

sample code2 : commons scheduler(just runnable component).This code above is good on local SDK. On AEM cloud, doesn't work.

 

import org.osgi.service.component.annotations.Component;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Component(service = Runnable.class, property = { Scheduler.PROPERTY_SCHEDULER_EXPRESSION + "=0 30 * * * ? " })
public class Myjob implements Runnable {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());
    
    @Override
    public void run() {
        logger.info("this message is from myjob");
    }
}

 

 Please help me.

aem as a cloud service scheduler Sling Jobs

Accepted Solutions (1)

Accepted Solutions (1)

Avatar

Avatar

Jörg_Hoh

Employee

Total Posts

3.1K

Likes

1.0K

Correct Reply

1.1K

Avatar

Jörg_Hoh

Employee

Total Posts

3.1K

Likes

1.0K

Correct Reply

1.1K
Jörg_Hoh
Employee

19-03-2021

Regarding the Sling Jobs: That works fine. You just need to be aware that the authoring service is provided by multiple AEM instances, which are clustered. Check the documentation at https://sling.apache.org/documentation/bundles/apache-sling-eventing-and-job-handling.html#job-distr... how to deal with clustered environments. 

 

Regarding the Sling Scheduler: That should work fine. It fires every hour at 30 min, that means at 2:30am, 3:30am, ...

Answers (2)

Answers (2)

Avatar

Avatar

khamat_bn

Avatar

khamat_bn

khamat_bn

19-03-2021

Hi  @watopin ,

 

Sling Job will work for this and the issue for the sling job that you poiniting is because of the Sling job lifecycle. 

If you check the sling job instances which are created for the same Topic is more, and that's what we need to manage. 

There Should be only one instance available for One Topic.

 

We can achieve this one by removing the Scheduled Sling Job first 

IMG_6594.jpg

IMG_6593.jpg

 once we have removed the Scheduled Job then we can start our Sling Job.

 

If we not do this way then every time new instance of Schedule job will created and every install of that job will trigger at required time.

Avatar

Avatar

bilala23933647

Avatar

bilala23933647

bilala23933647

19-03-2021

Hey @watopin try this:

import org.osgi.service.component.annotations.Component;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Component(service = Runnable.class, property = { "scheduler.expression=0 30 * * * ?" })
public class Myjob implements Runnable {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());
    
    @Override
    public void run() {
        logger.info("this message is from myjob");
    }
}

 

Thanks,

Bilal.