Expand my Community achievements bar.

Learn about Edge Delivery Services in upcoming GEM session

AEM as Cloud Service - Sling Jobs Triggering Twice

Avatar

Community Advisor

Hi All,

 

I have a use case for executing sling jobs only on one of the publish instance (I want this to run only once). But it looks like the job is getting completed on all the publish instances, i.e., twice.

 

In Sling Job I do not see an option for running it on CLUSTER like how we have in Scheduler.

 

Any pointers?

 

@Component(
immediate = true,
service = JobConsumer.class,
property = {
JobConsumer.PROPERTY_TOPICS + "=aem/something"
}
)
@Designate(ocd = ReportGenerationConfig.class)
public class ReportGenerationJobConsumer implements JobConsumer {
// Some code
}

 

Thanks,

Asutosh

15 Replies

Avatar

Employee Advisor

Hi,

 

this is not possible, because the publish instances do not know each other. Also depending on the type of deployment their number can vary. In would always recommend to execute such activities on author whenever possible.

Avatar

Community Advisor

But here the expectation is to run this on publish instance.

Avatar

Employee Advisor

Yes, but you cannot designate a publish instance "to be the one" which executes these jobs, at least not with the tooling provided by AEM itself. 

 

Of course you can create a new runmode "PublishWithSlingJobs", configure one of your publishs to have it and then start of the job based on that runmode criteria. Of course you need to be aware that this publish must always run and that you reconfigure another publish to have this runmode if the designated instance goes down either for a longer period of time or forever.

Avatar

Community Advisor

In the cloud, there is no such concept of custom run modes so I can create something like "publishwithslingjobs".

Avatar

Employee Advisor

Oh sorry, overlooked the reference to Cloud Service. And yes, you are totally correct, that you cannot manage custom runmodes with AEM as a Cloud Service.

 

 

Avatar

Community Advisor

Hi @Asutosh_Jena_ , Is it possible to share the task happening in publish or the reason to select in publisher? It doesn't seem to be possible running it on a single pod publisher. If the use case allows, you can try to see if same can be done in author and then publish it.

Avatar

Level 4

Hi @Asutosh_Jena_  

One way to make a Sling job run only on one instance in a publish cluster is to use the instance-aware parameter of the @Component annotation. You can refer this article for more details - https://medium.com/@monendra80/execute-sling-job-only-on-one-aem-publish-instance-bec62f2b3faa

 

Hope this helps.

Thanks

Monendra

Avatar

Community Advisor

Hi @Monendra_Singh 

There is no such parameter available as "instance-aware"!

 

 

Avatar

Community Advisor

I believe you are trying to post some data from one publish to third party.

You can ask consumer to put a time check e.g. last request time and reject subsequent request from another publishers.



Arun Patidar

Avatar

Level 6

Hi @Asutosh_Jena_,

 

Have you tried using Discovery service and check for isLeader instance?

 

Thanks, 

Ram

Avatar

Community Advisor

@rampai Have not tried yet. Let me try and come back if it works for AEM as Cloud.

 

Avatar

Level 2

Did you try to run on author only and publish the result by code, I'm assuming you are creating a file on the dam so after generating that on the dam you can publish (doing the publish on your code not manually), that way you will have able the report on all publish instances as AEM Cloud could have several # of publish instances

Avatar

Level 2

Try the below option, if anyone else is still looking for answer:

Use the TopologyEventListener to get the sling id associated with each instance in cluter environment and elect the leader based on the sling id; For example, select the instance which has highest sling id as leader instance.

 

 

public void handleTopologyEvent(TopologyEvent topologyEvent) {
	String leaderSlingId = StringUtils.EMPTY;
	Set<InstanceDescription> instances = topologyEvent.getNewView().getInstances();
	
	for (InstanceDescription desc : instances) {
		if (leaderSlingId.isEmpty()) {
			leaderSlingId = desc.getSlingId();
		} else if (leaderSlingId.compareTo(desc.getSlingId()) > 0) {
			leaderSlingId = desc.getSlingId();
		}
	}
	topologyEvent.getNewView().getLocalInstance().getSlingId().equals(leaderSlingId);
}

 

 

 

 

 
 

Avatar

Community Advisor

@bharath_kumark 

 

Its mentioned in other replies that publish instances do not know each other.

 

Out of curiosity, the code that you have shared to elect using slingID, this is for:

  • AEM 6.5 or AEMaaCS?
  • Author/publish?

 

I am confused looking at contradictory statements. Some clarity would help !


Aanchal Sikka

Avatar

Level 2

Hi @aanchal-sikka ,

 

The above code is written in AEM 6.5 version but in cloud version we can use the DiscoveryService to get the leader instance information like below. 

 

discoveryService.getTopology().getLocalInstance().isLeader();

 

Please let us know if this works.

 

Thanks!