Как создать динамически запланированную задачу?

Я пытаюсь создать приложение, которое имитирует открытие вкладки в баре. Я столкнулся с одной проблемой, которую я не могу понять - это выглядит следующим образом:

  1. Когда кто-то открывает вкладку панели, динамически создавайте запланированную задачу, которая выполняет код для закрытия вкладки через 24 часа.

  2. Если вкладка закрывается до истечения 24 часов, отмените запланированное задание.

  1. Если вкладка не закрывается через 24 часа, выполните код, описанный в шаге 1, чтобы инициировать платеж с карты, использованной для открытия вкладки.

Первоначально я изучал функции Firebase и думал об использовании вызываемой функции setTimeout(), но после некоторых исследований я обнаружил, что функцию Firebase нельзя вызывать дольше 9 минут.

ПРИМЕЧАНИЕ. Я хотел бы, чтобы это было динамическим. Это означает, что он учитывает переменное количество пользователей. На платформе может быть 100 или 1000 пользователей, каждому из них нужна возможность иметь для него уникальное запланированное задание (иногда несколько для каждого пользователя).

Могу я предложить несколько небольших советов по написанию хороших вопросов? Спрашивать «лучший способ» очень субъективно, если вы не определяете объективные критерии «лучшего». Просто сформулируйте свой вопрос так: «Как я могу создавать динамически запланированные задачи». Кроме того, фразы типа «пожалуйста, дайте мне знать, какое, по вашему мнению, решение этой проблемы является лучшим» являются пустяками и могут быть опущены. Мы все понимаем, что вы хотите получить ответ... потому что вы задали вопрос.

Wyck 20.12.2020 02:05
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
7
1
558
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Полное решение смотрите в комментариях.

Есть несколько способов обойти правило 10 минут (которое распространено в бессерверном коде), но вот что может вам помочь. Предлагаю разделить задачу на три:

  1. Облачная функция, закрывающая вкладку при вызове.
  2. Функция расписания, которая его вызывает (https://firebase.google.com/docs/functions/schedule-functions)
  3. Способ запуска и остановки функции расписания.

Я не знаю, как работает функция firebase, но раньше я работал с функциями Azure, и ими можно управлять с помощью командной строки (CLI) или с помощью SDK для выбранного вами языка. Чтобы отменить с помощью командной строки, попробуйте что-то вроде этого:

firebase functions:delete scheduledFunction

от Как отменить запланированную функцию firebase?.

Теперь осталось выяснить, как запустить функцию и можно ли передать параметр для ее планирования.

Удачи!

Спасибо за ответ! У меня есть еще несколько вопросов. Когда создается функция расписания, могу ли я создавать ее динамически (для нескольких пользователей и передавать необходимую платежную информацию этим запланированным функциям)? Кроме того, есть ли способ однозначно идентифицировать запланированное задание, чтобы я мог удалить его, если пользователь закроет вкладку?

devon66h 20.12.2020 01:22

@Devon Я не слишком знаком с облачными функциями, но вы можете однозначно идентифицировать их по имени. В лазурном мире есть уникальный идентификатор экземпляра, но я не уверен, что он доступен. Я рекомендую не передавать информацию об оплате/пользователе непосредственно в запланированную функцию. Вы должны хранить это в базе данных, и об этом позаботится основная облачная функция.

yichiz 20.12.2020 01:37

Что касается платежной информации, я использую API Stripe, поэтому она надежно обрабатывается там. Я бы просто передал планировщику идентификатор клиента пользователя. Я думаю, что я все еще не совсем уверен, скажем, пользователь А открывает вкладку в 8 вечера, а пользователь Б открывает вкладку в 8:30 вечера. Я хочу создать динамически запланированную функцию для обоих пользователей, чтобы точно закрыть свои вкладки 24 часа спустя (8 и 20:30 соответственно). Сможет ли это решение сделать это для меня? Я мог бы что-то пропустить здесь. Спасибо за вашу помощь.

devon66h 20.12.2020 01:52

@Devon Да, передача планировщику только идентификатора клиента безопасна. Обычно это POST-запрос для его запуска, и вы можете поместить эту информацию в тело. Я имею в виду создание одной функции для каждого пользователя. Таким образом, у вас должна быть функция расписания, называемая чем-то вроде scheduleUser1 с CRON, установленным на ('0 20 * * *'), и второй scheduleUser2 с CRON, установленным на ('30 20 * * *). Я использовал crontab.guru/#0_8___* для генерации CRON.

yichiz 20.12.2020 02:12

Однако, если у вас много пользователей, у вас будет много функций.

yichiz 20.12.2020 02:13

Понял, в этом есть смысл. Что, если пользовательская база является переменной (пользователи добавляются ежедневно)? Я получаю ваше решение, если пользовательская база фиксирована, но если бы это было масштабируемо, как я мог бы объяснить это? Спасибо.

devon66h 20.12.2020 16:05

Это отличный вопрос. Если существует ограничение на количество функций, которые вы можете создать в облаке, это не идеально, если количество пользователей увеличивается. Обычно бессерверные функции не имеют состояния, поэтому вы не должны сохранять данные (userId) для их идентификации. Вероятно, есть способы обойти это, но вам придется немного покопаться. Если нет, я рекомендую создать и развернуть типичный сервер node js (или технологию по вашему выбору).

yichiz 20.12.2020 18:07

Понял, спасибо за всю вашу помощь. Я думал о развертывании сервера Express, который будет обрабатывать эту функциональность. ИЛИ Я также рассматривал возможность запуска задания CRON каждую минуту в функциях Firebase, которое перебирает все открытые вкладки в Firestore, чтобы проверить, является ли время, когда его нужно закрыть, <= текущим временем - в этом случае закройте его. Какой вариант вы считаете лучшим?

devon66h 20.12.2020 18:44

Ну, это зависит от того, насколько точной / чувствительной ко времени вам нужна задача. Если точность времени задачи около минуты в порядке, то вы можете запускать запланированную функцию каждую минуту, чтобы проверять ВСЕ вкладки (или заказы) и закрывать те, срок действия которых истек. Я предполагаю, что эти вкладки хранятся в базе данных? Модель этой вкладки должна включать userId, startTime и isActive. Этот вариант лучше, чем развертывание собственного экспресс-сервера, если вы можете пожертвовать точностью ради более легкой масштабируемости и гораздо более низкой стоимости.

yichiz 20.12.2020 19:28

Да +/- одна минута вполне подходит для этого проекта, и да, все хранится в базе данных (userId, closeTimestamp, статус). Думаю реализовать это решение. Спасибо за все что ты сделал для меня!

devon66h 20.12.2020 19:39

Другие вопросы по теме