• Час читання ~2 хв
  • 04.07.2022

 

Один із методів магії

 

Photo by Jad Limcaco on Unsplash

Обмежувач швидкості повинен бути однією з найбільш непомічених функцій у Laravel. Для тих, хто новачок в Rate Limiter, суть його проста для розуміння: «оцінювати» щось, виходячи з максимальної кількості спроб всередині вікна часу.

Звичайна і найпоширеніша процедура використання обмежувача швидкості полягає в тому, щоб, по-перше, перевірити, чи не було зроблено занадто багато спроб ключа. Якщо цей ключ є в наявності, тільки тоді ми переходимо до виконання нашої логіки. Нарешті, ми збільшуємо кількість спроб по вікні часу до «розпаду».

Це, по суті, двоетапна логіка.

Вищесказане перекладається в «Якщо foo ключ був зроблений більше 5 разів, поверніть що-небудь. В іншому випадку виконуйте логіку, і збільшуйте foo спроби протягом наступних 60 секунд».

Іншими словами, якщо зробити спробу ключа foo більше 5 разів за 60 секунд, tooManyAttempts() то повернеться true і нічого не буде виконано.

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

Мені подобається один лайнер, і я зовсім недавно отримав схвалення маленького помічника під назвою attempt(), який повинен приземлитися в Laravel 8.53. Те, що він робить, - це те ж саме, але за допомогою зворотного дзвінка, і з тим же замовчуванням 60 секунд. Наш приклад, наведений вище, можна відновити лише в умовному твердженні:

Оскільки він отримує a Closure, обмеження ставки може стати портативним. Наприклад, ви можете зберегти функцію на початку та виконати її пізніше, замість того, щоб одружувати обмеження, що обмежує швидкість, на все, що у вас є між перевіркою та хітом. В якості альтернативи ви завжди можете використовувати a callable за допомогою Closure::fromCallable().

Найкраща реалізація полягає у attempt() створенні ідемпотентних викликів. Наприклад, уявіть, що ми хочемо надіслати повідомлення користувачеві, але пропустіть всю логіку, якщо повідомлення точно таке ж, яке він надіслав менше 2 хвилин тому. Це може статися, якщо з'єднання нестабільне, або коли користувач випадково натискає «Надіслати» занадто багато разів.

Немає проблем, ми можемо отримати хеш повідомлення як ключ, а потім перевірити, чи було воно надіслано раніше.

Останнє круте в attempt() тому, що він поверне результат зворотного дзвінка. Коли зворотний дзвінок нічого не повертає, або null, attempt() повернеться true.

Наприклад, якщо ми хочемо повернути модель, не проблема. Якщо зворотний дзвінок не був виконаний через те, що він досяг ліміту ставки, то false завжди повертається.

Comments

No comments yet
Yurij Finiv

Yurij Finiv

Full stack

Про мене

Professional Fullstack Developer with extensive experience in website and desktop application development. Proficient in a wide range of tools and technologies, including Bootstrap, Tailwind, HTML5, CSS3, PUG, JavaScript, Alpine.js, jQuery, PHP, MODX, and Node.js. Skilled in website development using Symfony, MODX, and Laravel. Experience: Contributed to the development and translation of MODX3 i...

Про автора CrazyBoy49z
WORK EXPERIENCE
Контакти
Ukraine, Lutsk
+380979856297