Как предотвратить выполнение остальной части экземпляра обратного вызова после завершения второго экземпляра? - PullRequest
2 голосов
/ 04 июня 2019

Я пишу программу для клиента MQTT, используя библиотеку PubSubClient.

Способ запустить функцию после получения сообщения в подписанной теме - реализовать функцию обратного вызова и передать ее в качестве параметра методу setCallback () библиотеки.

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

Есть ли какой-либо шаблон проектирования для достижения этой цели? Может быть, с помощью многозадачности (несколько потоков), или с помощью цифровой записи для запуска ISR, или любым другим способом ..?


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


Для примера спросили, ну, если бы я дал полный пример, то это был бы TL; DR, но вот что происходит.

Функция обратного вызова получает тему и сообщение, отправленное брокером MQTT.
Поэтому я использую некоторые операторы IF, чтобы решить, какую функцию следует вызвать Теперь, при определенном условии, мне нужно Publish (по значению MQTT) номер в теме. Кроме того, в другом состоянии я должен изменить это число перед публикацией.
Итак, как вы уже понимаете, есть сценарий, когда я получаю сообщение для публикации и сразу после этого, но перед публикацией я получаю второе сообщение, которое говорит, скажем, «Изменить».

Что происходит, когда я готовлюсь к публикации, я получаю второе сообщение, и поэтому «вложенный» обратный вызов меняет то, что я собираюсь опубликовать. Конечно, к тому времени, когда я опубликую MQTT, брокер ожидает изменения значений.

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

В целом, это не реальная проблема, поскольку, если Брокер получает неверные данные, он отвечает сообщением об ошибке, которое я улавливаю. Но я подумал, что, если бы я мог предотвратить это даже, дизайн был бы намного лучше.


Пример кода:

//In setup
client.setCallback(callback);        
mqttReconnect();

.

// The callback
void callback(char* topic, byte* payload, unsigned int length) {
if(topic == CHANGE){
  askBrokerForMoreInstructions(); // this functions will take as much time as the broker needs to respond..
} else if(topic == PUBLISH){
  doSomeCalculations();
  client.publish(topic,charArray);
}...

Что я забыл упомянуть, так это то, что когда я получаю что-то в теме ИЗМЕНЕНИЯ, я должен ждать больше инструкций, поэтому я получаю второй обратный вызов, второе полученное сообщение содержит информацию, которую я должен обработать в doSomeCalculations прежде чем я опубликую. Поэтому, когда второй обратный вызов завершается (и если это был приказ на ИЗМЕНЕНИЕ), нет смысла публиковать первый.

...