Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 4 Next »

Scheduled Tasks

We use following code to send pending reminders. This code is triggered at 5 minutes intervals. We use cluster locks (line 622) to ensure that only one instance of this task is running and if a new tasks is triggered before the previous task finished we simply skip new task.

We don't know whether the cluster locks are reentrant or not. So we also have an additional guard with an instance level "sendingReminders" flag (line 614).

Worst case scenario is sending a reminder will be delayed 5 more minutes. 

    if (this.sendingReminders) {
      log.warn("The add-on received a send pending reminders request while already processing reminders. You may be sending too many reminders, for example you may sending a reminder to large jira user group");
      return;
    }

    log.debug("Acquiring cluster lock for sending reminders");
    ClusterLock lock = clusterLockService.getLockForName(ReminderServiceImp.class.getName() + ".SendPendingReminders");
    boolean lockAcquired = lock.tryLock();
    if (!lockAcquired) {
      log.warn("Previous instance still running");
      return;
    }
    log.debug("Acquired cluster lock for sending reminders");
    try {
      sendPendingRemindersImp();
    } catch (Exception e) {
      log.error("Can't send pending reminders", e);
    } finally {
      this.sendingReminders = false;
      log.debug("Releasing cluster lock for sending reminders");
      lock.unlock();
    }

Transaction Management & Resource Usage

The add-on sends two type of reminders, user created reminders for issues and due date reminders for issues.

User Created Reminders: We only retrieve active reminders (which are not triggered yet) when querying reminders to be sent Although users may create more than one reminder for a single issue, most issues don’t require any reminder. In a normal usage, number of active reminders should be very small compared to the number of issues or users. We have also considered to use activeObjects.stream instead of following code segment but we need to modify Reminder object as not active and stream is returning read-only instances.

    Query query = Query.select().where("ACTIVE = ?", Boolean.TRUE);
    Reminder[] reminders = activeObjects.find(Reminder.class, query);

For Global Due Date Reminders: We first query issues due within specified hours. We do this using JQL using PagerFilter.getUnlimitedFilter. We use unlimited query because our JQL is already very restricted, it only returns issues due within specific hours. 


Functionality: Application Components

Our add-on adds a web panel to issue right context. Thanks to Jira, even if there is an exception in code path that provides this web panel Jira still displays rest of the issue and only an error is displayed inside the web panel. We use Velocity Templates to render this web panel, it is not loaded with Ajax. Our Reminder active object is annotated with @Preload annotation and has index on issue id field. When an issue is viewed we try to load reminders of the issue. So in sort, we add one more database call to get reminders of an issue.


Security

All panels for the add-on are rendered using Velocity Template Engine and we use #enable_html_escaping() directive to prevent injection. We also use @RequiresXsrfCheck annotation and ${atl_token} inside forms to prevent request forgery.



  • No labels