Повідомлення з'явилося через двадцять хвилин після підключення. Лічильник під ним ішов від учорашнього ранку, або від останньої автентифікації облікового запису, і ніщо в попередженні не казало, від чого саме. Це і є симптом: нагадування, прив'язане не до того з'єднання, яке перед вами.

Рішення не в кращому попередженні. Воно в тому, щоб визначити, який годинник має на увазі вимога, і потім прив'язати таймер до об'єкта, який існує в цьому годиннику.

Що спрацювало і що воно рахувало

Три ймовірні джерела дають одне й те саме повідомлення. Правило календаря працює у фіксований місцевий час і нічого не знає про тунелі. Лічильник у клієнті накопичується, поки підняте будь-яке з'єднання, і переживає повторні підключення. Політика шлюзу завершує сесію на боці сервера і спершу надсилає попередження.

Лише останні два стосуються сесії, і навіть вони розходяться. Лічильник клієнта вимірює те, що спостерігав локальний процес; шлюз вимірює те, що він автентифікував і облікував. Сон, зміна мережі або перезапуск спостерігача можуть розвести їх на години, і саме тому попередження та примусове завершення розходяться.

Три годинники за однією вимогою

Почніть із того, щоб записати речення, яке вам справді потрібне. Попередити до того, як шлюз завершить це з'єднання, — не та сама вимога, що нагадати після доби підключеного часу. Це й не те саме, що повідомити про те, що ця сесія триває вже 23 години. Кожна версія називає іншу подію, і відповідати на неї має інший компонент.

Потім перевірте, чи є дані. Локальна відмітка часу початку дає вік сесії без залежності від сервера. Політика шлюзу дає залишковий термін життя, але лише якщо шлюз його розкриває. Звіт про використання дає тривалість після факту, а це не може керувати попереднім сповіщенням.

Прив'яжіть таймер до сесії, а не до облікового запису

Спершу виберіть об'єкт. Обліковий запис може тримати кілька пристроїв і кілька одночасних сесій, тому нагадування, прив'язане до імені користувача, не може сказати, яке з'єднання досягло віку. Прив'яжіть його до профілю та цієї активації, а коли активація завершиться, скасуйте очікуване сповіщення.

Evidence you can readWhat it establishesWhere it misleads
Connection state changes to activeA session started nowDoes not carry the gateway's own session identifier
Duration reported at disconnectTotal service time for that sessionArrives too late for any advance notice
Interim usage updateTime accounted up to that updateStaleness equals the update interval
Local timestamp taken at activationAge of your observationResets whenever the observer restarts

Ця таблиця — контракт для вашого власного сповіщувача, а не опис API зворотного виклику будь-якого клієнта. Усе, що встановлений продукт документує про стан з'єднання, і є джерелом, до якого треба прив'язуватися; там, де він розкриває лише події автентифікації, скажіть це вголос і прийміть грубішу поведінку замість того, щоб виводити сесію.

Перевірте коротким порогом

Ніколи не налагоджуйте добовий таймер добовим очікуванням. Додайте настроюваний поріг, поставте його на тридцять секунд і виконайте чотири переходи по черзі: підключення, очікування, відключення, повторне підключення. Кожен перехід має дати рівно одну зміну стану, а повторне підключення має призначити новий термін, а не успадкувати старий.

# current connection state and profile identity
nmcli -f GENERAL.STATE,GENERAL.CONNECTION connection show work

# the notifier unit you wrote: does it restart the deadline or resume it?
journalctl --user -u vpn-timer.service --since "-5 min" -o cat

Дивіться на відмітки часу, а не на формулювання. Сповіщення, що приходить із часом початку попередньої сесії, прив'язало не той об'єкт, а сповіщення, що приходить двічі на один термін, означає, що прапорець надіслано так і не був збережений.

Сон, повторне підключення і втрачена доставка

Сон ламає обидва наївні рішення. Монотонний відлік зупиняється, поки машина спить, термін за настінним годинником продовжує рухатися, а таймер, що спрацював під час сну, доставляється пізно або не доставляється зовсім. Вирішіть, якої поведінки потребує ваша вимога, потім приспіть машину за порогом і підтвердьте це.

Доставка заслуговує такої ж турботи. Якщо сповіщення не можна показати, поставте його в чергу і перед остаточним показом ще раз перевірте, чи існує цільова сесія; інакше користувача попередять про з'єднання, яке вже завершилося. Примусове відключення та оновлення облікових даних залишаються поза цим шляхом, бо нагадування, яке тихо змінює долю з'єднання, — це рішення політики, вдягнене в сповіщення.

Схожі статті