Лучшим способом решения этой проблемы может быть использование ProcessFunction, а не настраиваемое управление окнами. Если, как показано в вашем примере, события будут обрабатываться в порядке отметок времени, то это будет довольно просто. Если, с другой стороны, вам нужно обрабатывать неупорядоченные события (что часто случается при работе с данными времени события), это будет несколько сложнее. (Представьте, что сообщение msg6 с временем 187 приходит после t8. Если это возможно и если это повлияет на результаты, которые вы хотите получить, то это нужно обработать.)
Если события в порядке, тогда логика будет выглядеть примерно так:
Используйте AscendingTimestampExtractor в качестве основы для водяных знаков.
Используйте состояние Flink (возможно, ListState) для хранения содержимого окна. Когда событие приходит, добавьте его в окно и проверьте, прошло ли оно более 180 секунд с момента первого события. Если это так, обработайте содержимое окна и очистите список.
Если ваши события могут быть не в порядке, используйте BoundedOutOfOrdernessTimestampExtractor и не обрабатывайте содержимое окна до тех пор, пока currentWatermark не покажет, что время события прошло через 180 секунд после времени начала окна (вы можете использовать таймер времени события за это). Не полностью очищайте список при запуске окна, а просто удалите элементы, принадлежащие закрывающемуся окну.