All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.opentcs.kernel.workingset.WorkingSetCleanupTask Maven / Gradle / Ivy

There is a newer version: 6.1.2
Show newest version
// SPDX-FileCopyrightText: The openTCS Authors
// SPDX-License-Identifier: MIT
package org.opentcs.kernel.workingset;

import static java.util.Objects.requireNonNull;

import jakarta.inject.Inject;
import java.util.Objects;
import java.util.function.Predicate;
import org.opentcs.customizations.kernel.GlobalSyncObject;
import org.opentcs.data.TCSObjectReference;
import org.opentcs.data.order.OrderSequence;
import org.opentcs.data.order.TransportOrder;
import org.opentcs.data.peripherals.PeripheralJob;
import org.opentcs.kernel.OrderPoolConfiguration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * A task that periodically removes orders, order sequences and peripheral jobs in a final state.
 */
public class WorkingSetCleanupTask
    implements
      Runnable {

  /**
   * This class's Logger.
   */
  private static final Logger LOG = LoggerFactory.getLogger(WorkingSetCleanupTask.class);
  /**
   * A global object to be used for synchronization within the kernel.
   */
  private final Object globalSyncObject;
  /**
   * Keeps all the transport orders.
   */
  private final TransportOrderPoolManager orderPoolManager;
  /**
   * Keeps all peripheral jobs.
   */
  private final PeripheralJobPoolManager peripheralJobPoolManager;
  /**
   * This class's configuration.
   */
  private final OrderPoolConfiguration configuration;
  /**
   * Checks whether an order sequence may be removed.
   */
  private final CompositeOrderSequenceCleanupApproval compositeOrderSequenceCleanupApproval;
  /**
   * Checks whether a transport order may be removed.
   */
  private final CompositeTransportOrderCleanupApproval compositeTransportOrderCleanupApproval;
  /**
   * Checks whether a peripheral job may be removed.
   */
  private final CompositePeripheralJobCleanupApproval compositePeripheralJobCleanupApproval;
  /**
   * Keeps track of the time used to determine whether a working set item should be removed
   * (according to its creation time).
   */
  private final CreationTimeThreshold creationTimeThreshold;

  /**
   * Creates a new instance.
   *
   * @param globalSyncObject The kernel threads' global synchronization object.
   * @param orderPoolManager The order pool manager to be used.
   * @param peripheralJobPoolManager The peripheral job pool manager to be used.
   * @param compositeOrderSequenceCleanupApproval Checks whether an order sequence may be removed.
   * @param compositeTransportOrderCleanupApproval Checks whether a transport order may be removed.
   * @param compositePeripheralJobCleanupApproval Checks whether a peripheral job may be removed.
   * @param creationTimeThreshold Keeps track of the time used to determine whether a working set
   * item should be removed (according to its creation time).
   * @param configuration This class's configuration.
   */
  @Inject
  public WorkingSetCleanupTask(
      @GlobalSyncObject
      Object globalSyncObject,
      TransportOrderPoolManager orderPoolManager,
      PeripheralJobPoolManager peripheralJobPoolManager,
      OrderPoolConfiguration configuration,
      CompositeOrderSequenceCleanupApproval compositeOrderSequenceCleanupApproval,
      CompositeTransportOrderCleanupApproval compositeTransportOrderCleanupApproval,
      CompositePeripheralJobCleanupApproval compositePeripheralJobCleanupApproval,
      CreationTimeThreshold creationTimeThreshold
  ) {
    this.globalSyncObject = requireNonNull(globalSyncObject, "globalSyncObject");
    this.orderPoolManager = requireNonNull(orderPoolManager, "orderPoolManager");
    this.peripheralJobPoolManager = requireNonNull(
        peripheralJobPoolManager,
        "peripheralJobPoolManager"
    );
    this.compositeOrderSequenceCleanupApproval
        = requireNonNull(compositeOrderSequenceCleanupApproval);
    this.compositeTransportOrderCleanupApproval
        = requireNonNull(compositeTransportOrderCleanupApproval);
    this.compositePeripheralJobCleanupApproval
        = requireNonNull(compositePeripheralJobCleanupApproval);
    this.creationTimeThreshold = requireNonNull(creationTimeThreshold, "creationTimeThreshold");
    this.configuration = requireNonNull(configuration, "configuration");
  }

  public long getSweepInterval() {
    return configuration.sweepInterval();
  }

  @Override
  public void run() {
    synchronized (globalSyncObject) {
      LOG.debug("Sweeping working set...");

      // Update the creation time threshold for this cleanup run.
      creationTimeThreshold.updateCurrentThreshold(configuration.sweepAge());

      // Remove all peripheral jobs in a final state that do not belong to a transport order and
      // that are older than the threshold.
      Predicate noRelatedTransportOrder = job -> job
          .getRelatedTransportOrder() == null;
      for (PeripheralJob peripheralJob : peripheralJobPoolManager.getObjectRepo().getObjects(
          PeripheralJob.class,
          noRelatedTransportOrder.and(compositePeripheralJobCleanupApproval)
      )) {
        peripheralJobPoolManager.removePeripheralJob(peripheralJob.getReference());
      }

      // Remove all transport orders in a final state that do NOT belong to a sequence and that are
      // older than the threshold, including their related peripheral jobs.
      Predicate noWrappingSequence = order -> order.getWrappingSequence() == null;
      for (TransportOrder transportOrder : orderPoolManager.getObjectRepo().getObjects(
          TransportOrder.class,
          noWrappingSequence.and(compositeTransportOrderCleanupApproval)
      )) {
        removeRelatedPeripheralJobs(transportOrder.getReference());
        orderPoolManager.removeTransportOrder(transportOrder.getReference());
      }

      // Remove all order sequences that have been finished, including their transport orders and
      // the transport orders' related peripheral jobs.
      for (OrderSequence orderSequence : orderPoolManager.getObjectRepo().getObjects(
          OrderSequence.class,
          compositeOrderSequenceCleanupApproval
      )) {
        for (TCSObjectReference transportOrderRef : orderSequence.getOrders()) {
          removeRelatedPeripheralJobs(transportOrderRef);
        }
        orderPoolManager.removeFinishedOrderSequenceAndOrders(orderSequence.getReference());
      }
    }
  }

  private void removeRelatedPeripheralJobs(TCSObjectReference transportOrderRef) {
    for (PeripheralJob peripheralJob : peripheralJobPoolManager.getObjectRepo().getObjects(
        PeripheralJob.class,
        job -> Objects.equals(job.getRelatedTransportOrder(), transportOrderRef)
    )) {
      peripheralJobPoolManager.removePeripheralJob(peripheralJob.getReference());
    }
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy