Code review comment: `SYNCHRONIZED_PROCESSING_TIME`?  Why is this the case? Specifically, why do we consider event time timers?

Code under review:
public void onTimers(Iterable<TimerData> timers) throws Exception {
    if (!timers.iterator().hasNext()) {
      return;
    }

    
    
    Map<BoundedWindow, EnrichedTimerData> enrichedTimers = new HashMap();

    for (TimerData timer : timers) {
      checkArgument(timer.getNamespace() instanceof WindowNamespace,
          "Expected timer to be in WindowNamespace, but was in %s", timer.getNamespace());
      @SuppressWarnings("unchecked")
        WindowNamespace<W> windowNamespace = (WindowNamespace<W>) timer.getNamespace();
      W window = windowNamespace.getWindow();

      WindowTracing.debug("{}: Received timer key:{}; window:{}; data:{} with "
              + "inputWatermark:{}; outputWatermark:{}",
          ReduceFnRunner.class.getSimpleName(),
          key, window, timer,
          timerInternals.currentInputWatermarkTime(),
          timerInternals.currentOutputWatermarkTime());

      
      
      if (TimeDomain.PROCESSING_TIME == timer.getDomain() && windowIsExpired(window)) {
        continue;
      }

      
      
      
      
      if (enrichedTimers.containsKey(window)) {
        continue;
      }

      ReduceFn<K, InputT, OutputT, W>.Context directContext =
          contextFactory.base(window, StateStyle.DIRECT);
      ReduceFn<K, InputT, OutputT, W>.Context renamedContext =
          contextFactory.base(window, StateStyle.RENAMED);
      EnrichedTimerData enrichedTimer = new EnrichedTimerData(directContext, renamedContext);
      enrichedTimers.put(window, enrichedTimer);

      
      if (enrichedTimer.isGarbageCollection) {
        triggerRunner.prefetchIsClosed(directContext.state());
      } else {
        triggerRunner.prefetchShouldFire(directContext.window(), directContext.state());
      }
    }

    
    for (EnrichedTimerData timer : enrichedTimers.values()) {
      if (timer.windowIsActiveAndOpen()) {
        ReduceFn<K, InputT, OutputT, W>.Context directContext = timer.directContext;
        if (timer.isGarbageCollection) {
          prefetchOnTrigger(directContext, timer.renamedContext);
        } else if (triggerRunner.shouldFire(
            directContext.window(), directContext.timers(), directContext.state())) {
          prefetchEmit(directContext, timer.renamedContext);
        }
      }
    }

    
    for (EnrichedTimerData timer : enrichedTimers.values()) {
      ReduceFn<K, InputT, OutputT, W>.Context directContext = timer.directContext;
      ReduceFn<K, InputT, OutputT, W>.Context renamedContext = timer.renamedContext;

      if (timer.isGarbageCollection) {
        WindowTracing.debug(
            "{}: Cleaning up for key:{}; window:{} with inputWatermark:{}; outputWatermark:{}",
            ReduceFnRunner.class.getSimpleName(),
            key,
            directContext.window(),
            timerInternals.currentInputWatermarkTime(),
            timerInternals.currentOutputWatermarkTime());

        boolean windowIsActiveAndOpen = timer.windowIsActiveAndOpen();
        if (windowIsActiveAndOpen) {
          
          
          
          @Nullable
          Instant newHold = onTrigger(
              directContext, renamedContext, true /* isFinished */, timer.isEndOfWindow);
          checkState(newHold == null, "Hold placed at %s despite isFinished being true.", newHold);
        }

        
        
        clearAllState(directContext, renamedContext, windowIsActiveAndOpen);
      } else {
        WindowTracing.debug(
            "{}.onTimers: Triggering for key:{}; window:{} at {} with "
                + "inputWatermark:{}; outputWatermark:{}",
            key,
            directContext.window(),
            timerInternals.currentInputWatermarkTime(),
            timerInternals.currentOutputWatermarkTime());
        if (timer.windowIsActiveAndOpen()
            && triggerRunner.shouldFire(
                   directContext.window(), directContext.timers(), directContext.state())) {
          emit(directContext, renamedContext);
        }

        if (timer.isEndOfWindow) {
          
          
          
          

          
          
          
          
          
          checkState(
              windowingStrategy.getAllowedLateness().isLongerThan(Duration.ZERO),
              "Unexpected zero getAllowedLateness");
          Instant cleanupTime =
              LateDataUtils.garbageCollectionTime(directContext.window(), windowingStrategy);
          WindowTracing.debug(
              "ReduceFnRunner.onTimer: Scheduling cleanup timer for key:{}; window:{} at {} with "
                  + "inputWatermark:{}; outputWatermark:{}",
              key, directContext.window(), cleanupTime, timerInternals.currentInputWatermarkTime(),
              timerInternals.currentOutputWatermarkTime());
          checkState(!cleanupTime.isAfter(BoundedWindow.TIMESTAMP_MAX_VALUE),
              "Cleanup time %s is beyond end-of-time", cleanupTime);
          directContext.timers().setTimer(cleanupTime, TimeDomain.EVENT_TIME);
        }
      }
    }
  }

Line commented on: if (TimeDomain.PROCESSING_TIME == timer.getDomain() && windowIsExpired(window)) {

Revised code:
public void onTimers(Iterable<TimerData> timers) throws Exception {
    if (!timers.iterator().hasNext()) {
      return;
    }

    
    
    Map<BoundedWindow, WindowActivation> windowActivations = new HashMap();

    for (TimerData timer : timers) {
      checkArgument(timer.getNamespace() instanceof WindowNamespace,
          "Expected timer to be in WindowNamespace, but was in %s", timer.getNamespace());
      @SuppressWarnings("unchecked")
        WindowNamespace<W> windowNamespace = (WindowNamespace<W>) timer.getNamespace();
      W window = windowNamespace.getWindow();

      WindowTracing.debug("{}: Received timer key:{}; window:{}; data:{} with "
              + "inputWatermark:{}; outputWatermark:{}",
          ReduceFnRunner.class.getSimpleName(),
          key, window, timer,
          timerInternals.currentInputWatermarkTime(),
          timerInternals.currentOutputWatermarkTime());

      
      
      if (TimeDomain.EVENT_TIME != timer.getDomain() && windowIsExpired(window)) {
        continue;
      }

      
      
      
      
      if (windowActivations.containsKey(window)) {
        continue;
      }

      ReduceFn<K, InputT, OutputT, W>.Context directContext =
          contextFactory.base(window, StateStyle.DIRECT);
      ReduceFn<K, InputT, OutputT, W>.Context renamedContext =
          contextFactory.base(window, StateStyle.RENAMED);
      WindowActivation windowActivation = new WindowActivation(directContext, renamedContext);
      windowActivations.put(window, windowActivation);

      
      if (windowActivation.isGarbageCollection) {
        triggerRunner.prefetchIsClosed(directContext.state());
      } else {
        triggerRunner.prefetchShouldFire(directContext.window(), directContext.state());
      }
    }

    
    for (WindowActivation timer : windowActivations.values()) {
      if (timer.windowIsActiveAndOpen()) {
        ReduceFn<K, InputT, OutputT, W>.Context directContext = timer.directContext;
        if (timer.isGarbageCollection) {
          prefetchOnTrigger(directContext, timer.renamedContext);
        } else if (triggerRunner.shouldFire(
            directContext.window(), directContext.timers(), directContext.state())) {
          prefetchEmit(directContext, timer.renamedContext);
        }
      }
    }

    
    for (WindowActivation windowActivation : windowActivations.values()) {
      ReduceFn<K, InputT, OutputT, W>.Context directContext = windowActivation.directContext;
      ReduceFn<K, InputT, OutputT, W>.Context renamedContext = windowActivation.renamedContext;

      if (windowActivation.isGarbageCollection) {
        WindowTracing.debug(
            "{}: Cleaning up for key:{}; window:{} with inputWatermark:{}; outputWatermark:{}",
            ReduceFnRunner.class.getSimpleName(),
            key,
            directContext.window(),
            timerInternals.currentInputWatermarkTime(),
            timerInternals.currentOutputWatermarkTime());

        boolean windowIsActiveAndOpen = windowActivation.windowIsActiveAndOpen();
        if (windowIsActiveAndOpen) {
          
          
          
          @Nullable
          Instant newHold = onTrigger(
              directContext, renamedContext, true /* isFinished */, windowActivation.isEndOfWindow);
          checkState(newHold == null, "Hold placed at %s despite isFinished being true.", newHold);
        }

        
        
        clearAllState(directContext, renamedContext, windowIsActiveAndOpen);
      } else {
        WindowTracing.debug(
            "{}.onTimers: Triggering for key:{}; window:{} at {} with "
                + "inputWatermark:{}; outputWatermark:{}",
            key,
            directContext.window(),
            timerInternals.currentInputWatermarkTime(),
            timerInternals.currentOutputWatermarkTime());
        if (windowActivation.windowIsActiveAndOpen()
            && triggerRunner.shouldFire(
                   directContext.window(), directContext.timers(), directContext.state())) {
          emit(directContext, renamedContext);
        }

        if (windowActivation.isEndOfWindow) {
          
          
          
          

          
          
          
          
          
          checkState(
              windowingStrategy.getAllowedLateness().isLongerThan(Duration.ZERO),
              "Unexpected zero getAllowedLateness");
          Instant cleanupTime =
              LateDataUtils.garbageCollectionTime(directContext.window(), windowingStrategy);
          WindowTracing.debug(
              "ReduceFnRunner.onTimer: Scheduling cleanup timer for key:{}; window:{} at {} with "
                  + "inputWatermark:{}; outputWatermark:{}",
              key, directContext.window(), cleanupTime, timerInternals.currentInputWatermarkTime(),
              timerInternals.currentOutputWatermarkTime());
          checkState(!cleanupTime.isAfter(BoundedWindow.TIMESTAMP_MAX_VALUE),
              "Cleanup time %s is beyond end-of-time", cleanupTime);
          directContext.timers().setTimer(cleanupTime, TimeDomain.EVENT_TIME);
        }
      }
    }
  }