You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by jo...@apache.org on 2022/06/06 13:23:31 UTC

[sling-org-apache-sling-event] 01/01: SLING-11379 do not register the same job over and over

This is an automated email from the ASF dual-hosted git repository.

joerghoh pushed a commit to branch SLING-11739
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-event.git

commit 836e7717c7b026d8c1f3cc0d5048359bf0339622
Author: Jörg Hoh <jo...@joerghoh.de>
AuthorDate: Mon Jun 6 15:21:41 2022 +0200

    SLING-11379 do not register the same job over and over
---
 .../sling/event/impl/jobs/JobBuilderImpl.java      |  2 +-
 .../jobs/scheduling/JobScheduleBuilderImpl.java    | 38 +++++++++++++++++++++-
 .../org/apache/sling/event/it/SchedulingIT.java    |  8 ++++-
 3 files changed, 45 insertions(+), 3 deletions(-)

diff --git a/src/main/java/org/apache/sling/event/impl/jobs/JobBuilderImpl.java b/src/main/java/org/apache/sling/event/impl/jobs/JobBuilderImpl.java
index a662066..06156fc 100644
--- a/src/main/java/org/apache/sling/event/impl/jobs/JobBuilderImpl.java
+++ b/src/main/java/org/apache/sling/event/impl/jobs/JobBuilderImpl.java
@@ -64,7 +64,7 @@ public class JobBuilderImpl implements JobBuilder {
         return new JobScheduleBuilderImpl(
                 this.topic,
                 this.properties,
-                UUID.randomUUID().toString(),
+                null, // correct value is calculated later
                 this.jobManager.getJobScheduler());
     }
 }
diff --git a/src/main/java/org/apache/sling/event/impl/jobs/scheduling/JobScheduleBuilderImpl.java b/src/main/java/org/apache/sling/event/impl/jobs/scheduling/JobScheduleBuilderImpl.java
index 7e46985..749ec2b 100644
--- a/src/main/java/org/apache/sling/event/impl/jobs/scheduling/JobScheduleBuilderImpl.java
+++ b/src/main/java/org/apache/sling/event/impl/jobs/scheduling/JobScheduleBuilderImpl.java
@@ -19,18 +19,23 @@
 package org.apache.sling.event.impl.jobs.scheduling;
 
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.Date;
 import java.util.List;
 import java.util.Map;
 
 import org.apache.sling.event.impl.support.ScheduleInfoImpl;
 import org.apache.sling.event.jobs.JobBuilder.ScheduleBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.apache.sling.event.jobs.ScheduledJobInfo;
 
 /**
  * The builder implementation for scheduled jobs.
  */
 public final class JobScheduleBuilderImpl implements ScheduleBuilder {
+    
+    private static final Logger logger = LoggerFactory.getLogger(JobScheduleBuilderImpl.class);
 
     private final String topic;
 
@@ -104,9 +109,13 @@ public final class JobScheduleBuilderImpl implements ScheduleBuilder {
 
     @Override
     public ScheduledJobInfo add(final List<String> errors) {
+        String finalScheduleName = scheduleName;
+        if (scheduleName == null) {
+            finalScheduleName = deriveScheduleName();
+        }
         return this.jobScheduler.addScheduledJob(topic,
                 properties,
-                scheduleName,
+                finalScheduleName,
                 suspend,
                 schedules,
                 errors);
@@ -117,4 +126,31 @@ public final class JobScheduleBuilderImpl implements ScheduleBuilder {
         this.suspend = true;
         return this;
     }
+
+    /**
+     * In case a scheduleName was not provided we calculate on based on the available
+     * data so we can detect duplicates.
+     * @return a value which is identical for identical jobs
+     */
+    private String deriveScheduleName() {
+        StringBuilder sb = new StringBuilder();
+        sb.append("topic="+topic)
+            .append(",suspend=" + suspend)
+            .append(",");
+
+        if (properties != null) {
+            // sort the properties and flatten them into a string
+            List<String> keys = new ArrayList<>(properties.keySet());
+            Collections.sort(keys);
+            for (String key: keys) {
+                sb.append(key).append("=").append(properties.get(key)).append(",");
+            }
+        }
+        // append all schedules
+        sb.append("schedules=").append(schedules);
+
+        String hashCode = new String("" + sb.toString().hashCode());
+        logger.debug("calculated hash [{}] for unspecified scheduleName, calculated as {}",hashCode, sb.toString());
+        return hashCode;
+    }
 }
diff --git a/src/test/java/org/apache/sling/event/it/SchedulingIT.java b/src/test/java/org/apache/sling/event/it/SchedulingIT.java
index c13b57b..d192eb3 100644
--- a/src/test/java/org/apache/sling/event/it/SchedulingIT.java
+++ b/src/test/java/org/apache/sling/event/it/SchedulingIT.java
@@ -18,6 +18,7 @@
  */
 package org.apache.sling.event.it;
 
+import java.util.Collections;
 import java.util.Date;
 import java.util.UUID;
 import java.util.concurrent.atomic.AtomicInteger;
@@ -77,6 +78,9 @@ public class SchedulingIT extends AbstractJobHandlingIT {
         assertNotNull(info2);
         final ScheduledJobInfo info3 = jobManager.createJob(TOPIC).schedule().weekly(3, 19, 12).add();
         assertNotNull(info3);
+        // This is a duplicate and won't be scheduled, as it is identical to the 3rd job
+        final ScheduledJobInfo info4 = jobManager.createJob(TOPIC).schedule().weekly(3, 19, 12).add();
+        assertNotNull(info4);
 
         assertEquals(3, jobManager.getScheduledJobs().size()); // scheduled jobs
         info3.unschedule();
@@ -106,7 +110,9 @@ public class SchedulingIT extends AbstractJobHandlingIT {
         });
         for(int i=0; i<NUM_ITERATIONS; i++) {
             logger.info("schedulingLoadTest: loop-" + i);
-            jobManager.createJob(ownTopic).schedule().at(new Date(System.currentTimeMillis() + 2500)).add();
+            jobManager.createJob(ownTopic)
+                .properties(Collections.singletonMap("prop", i))
+                .schedule().at(new Date(System.currentTimeMillis() + 2500)).add();
             Thread.sleep(1);
         }
         logger.info("schedulingLoadTest: done, letting jobs be triggered, currently at {} jobs, {} schedules", counter.get(), jobManager.getScheduledJobs().size());