Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Code Block
languagejava
firstline614
linenumberstrue
    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.

Code Block
languagejava
    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.