Actor Framework
- Cat
- adviser
- Сообщения: 203
- Зарегистрирован: 22 июл 2010, 09:53
- Версия LabVIEW: 12
- Контактная информация:
Re: Actor Framework
Спасибо коллеги, стало намного понятней! Действительно довольно просто, но немного непривычно, это отличается от явы ну и от классического LabVIEW.
Чеширский Кот - совсем не тот, что чешет языком.
-
taras_33
- professional
- Сообщения: 392
- Зарегистрирован: 31 окт 2009, 18:25
- Награды: 1
- Версия LabVIEW: 2019
- Поблагодарили: 13 раз
- Контактная информация:
Re: Actor Framework
Хорошие уроки, хоть и на британском английском, но достаточно доходчиво объясняет, особенно понравился девятый урок.
Кстати еще можно посмотреть его презентацию о том что такое OOP и AF и почему вы не должны этого боятся. (What is OOP and AF? And why you shouldn’t be scared of it) Ну и сам автор о себе
Кстати еще можно посмотреть его презентацию о том что такое OOP и AF и почему вы не должны этого боятся. (What is OOP and AF? And why you shouldn’t be scared of it) Ну и сам автор о себе
Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots.
So far, the Universe is winning!
So far, the Universe is winning!
-
IvanLis
- guru
- Сообщения: 5467
- Зарегистрирован: 02 дек 2009, 17:44
- Награды: 7
- Версия LabVIEW: 2015, 2016
- Откуда: СССР
- Благодарил (а): 28 раз
- Поблагодарили: 87 раз
Re: Actor Framework
Настало время для самообразованияIvanLis писал(а):Нужно себе на отпуск 19 запланировать![]()
В этом году разбирался с другими вопросами.
![:rtfm: :rtfm:](./images/smilies/icon_rtfm.gif)
Начал копать материалы в данном направлении, нашел урок от BLOOMY:
GETTING STARTED WITH THE ACTOR FRAMEWORK - PART I
GETTING STARTED WITH THE ACTOR FRAMEWORK – PART II
У них почему-то для незарегистрированных пользователей скачивание примеров не доступно, по этому дублирую их здесь:
Знание нескольких принципов освобождает от знания многих фактов!
Правила форума
Как добавить в сообщение картинку или файл
Конвертация / версий (форматов) VI
Как правильно задать вопрос...
Правила форума
Как добавить в сообщение картинку или файл
Конвертация / версий (форматов) VI
Как правильно задать вопрос...
- Juri
- I/O
- Сообщения: 263
- Зарегистрирован: 19 апр 2017, 23:06
- Версия LabVIEW: 2021
- Благодарил (а): 13 раз
- Поблагодарили: 6 раз
Re: Actor Framework
В своем проекте я использовал рекурсивный вызов state machine. Это позволяет упростить программирование. Например у меня есть vi которая включает в себя команду на опрос прибора. Внутри этой команды заложено много всего, например вызов блока который отправляет запрос в прибор, ожидание ответа прибора и сравнение ответа с ожидаемым результатом. С недавнего времени решил переделать проект под акторы. Возможно ли устроить такую же vi, которая будет делать много разных комбинаций действий и еще дожидаться отчета об их исполнении?
Вот пример:
Родительский актор EM EXT вызывает актор TCP. Потомок умеет подключаться к какому-нибудь серверу (нет в примере) по TCP. В результате подключения он отсылает отчет родителю с меткой Ok или Error. Родитель его получает. Меня интересует конкретно StartTCP.vi в родительском акторе. На выходе у него индикатор Ok? который должен быть true если актор TCP пошлет отчет об успешном подключении. Как сделать ожидание этого отчета внутри StartTCP.vi? Это позволит легко создавать целые последовательности действий на одном экране, типа подключись к прибору, спроси его параметры, включи режим тестирования и т.д., каждый пункт возможно будет содержать множество команд, на выходе из каждой должно быть подтверждение об ее исполнении.
Вот пример:
Родительский актор EM EXT вызывает актор TCP. Потомок умеет подключаться к какому-нибудь серверу (нет в примере) по TCP. В результате подключения он отсылает отчет родителю с меткой Ok или Error. Родитель его получает. Меня интересует конкретно StartTCP.vi в родительском акторе. На выходе у него индикатор Ok? который должен быть true если актор TCP пошлет отчет об успешном подключении. Как сделать ожидание этого отчета внутри StartTCP.vi? Это позволит легко создавать целые последовательности действий на одном экране, типа подключись к прибору, спроси его параметры, включи режим тестирования и т.д., каждый пункт возможно будет содержать множество команд, на выходе из каждой должно быть подтверждение об ее исполнении.
- Вложения
-
test.rar
- (369.7 КБ) 234 скачивания
-
Kosist
- expert
- Сообщения: 1236
- Зарегистрирован: 21 фев 2011, 23:44
- Награды: 2
- Версия LabVIEW: 2013-2020
- Благодарил (а): 23 раза
- Поблагодарили: 30 раз
- Контактная информация:
Re: Actor Framework
Я думаю Вы немного путаете понятия наследственности, и иерархии вызовов.
В Вашем случае актор, который будет получать отчеты не должен быть родительским по отношению к TCP актору, он его будет просто "вызывать", т.е. запускать.
А наследственность можно использовать для того, чтобы создать родительский актор который будет содержать абстрактные (т.е. "пустые", без конкретной имплементации) методы - напр., Connect, Disconnect, Send Message, и т.д., а его наследник уже будет конкретно имплементировать подлючение к серверу через TCP. Выгода в том, что если вдруг Ваше приложение будет общаться не при помощи TCP, а скажем при помощи OPC сервера - Вам не нужно будет переделывать работающий код; Вы просто создадите нового наследника, и имплементируете для него все методы. При этом, де-факто, в приложении на верхнем уровне, Вы используете методы (сообщения) родительского класса, который при своем вызове инициализируется как конкретный актор-наследник.
По поводу ожидания отчета - акторы "не приветствуют" такой подход. Т.е. актор не может быть заблокирован - он не обязан ожидать отчета от другого актора. Он просто работает, и если получил какое-то сообщение (комманду) - он его выполняет. Т.е. сама идея получения отчетов-подверждений отличная, но помните, что актор, который их получает не должен быть заблокирован их ожиданием - он их просто получает, и обрабатывает.
Поэтому создать подобие последствии действий можно так: Актор А посылает сообщение Актору Б подключиться к серверу -> Актор Б подключается, и отсылает Актору А сообщение типу "Сервер подключен" с параметром "Успешно=true". Актор А получает это сообщение, отсылает Актору Б сообщение "Ожидать данные" -> Актор Б считывает данные, и потом отсылает Актору А сообщение "Данные получены", и т.д. Т.е. после нужных шагов "главный" актор получает не одно сообщение типу "отчет", а конкретные сообщения состояния, внутри которых он имеет логику для перехода к следующему состоянию.
Выход-индикатор метода актора имеет смысл только для тех методов, которые не используются как сообщения - т.к. сообщения имеют лишь входящие данные. Поэтому, можете использовать channeling pattern - метод, который имеет на выходе индикатор состояния вызывается внутри метода, который может быть вызван при помощи сообщения. Таким образом, "главный" актор будет посылать нужному актору эти сообщения на исполнение, и таким образом внутри них будет вызываться вложенный метод + обрабатываться (отслыться в качестве отчета) индикатор выполнения.
Надеюсь, что не очень запутанно попытался объяснить...
В Вашем случае актор, который будет получать отчеты не должен быть родительским по отношению к TCP актору, он его будет просто "вызывать", т.е. запускать.
А наследственность можно использовать для того, чтобы создать родительский актор который будет содержать абстрактные (т.е. "пустые", без конкретной имплементации) методы - напр., Connect, Disconnect, Send Message, и т.д., а его наследник уже будет конкретно имплементировать подлючение к серверу через TCP. Выгода в том, что если вдруг Ваше приложение будет общаться не при помощи TCP, а скажем при помощи OPC сервера - Вам не нужно будет переделывать работающий код; Вы просто создадите нового наследника, и имплементируете для него все методы. При этом, де-факто, в приложении на верхнем уровне, Вы используете методы (сообщения) родительского класса, который при своем вызове инициализируется как конкретный актор-наследник.
По поводу ожидания отчета - акторы "не приветствуют" такой подход. Т.е. актор не может быть заблокирован - он не обязан ожидать отчета от другого актора. Он просто работает, и если получил какое-то сообщение (комманду) - он его выполняет. Т.е. сама идея получения отчетов-подверждений отличная, но помните, что актор, который их получает не должен быть заблокирован их ожиданием - он их просто получает, и обрабатывает.
Поэтому создать подобие последствии действий можно так: Актор А посылает сообщение Актору Б подключиться к серверу -> Актор Б подключается, и отсылает Актору А сообщение типу "Сервер подключен" с параметром "Успешно=true". Актор А получает это сообщение, отсылает Актору Б сообщение "Ожидать данные" -> Актор Б считывает данные, и потом отсылает Актору А сообщение "Данные получены", и т.д. Т.е. после нужных шагов "главный" актор получает не одно сообщение типу "отчет", а конкретные сообщения состояния, внутри которых он имеет логику для перехода к следующему состоянию.
Выход-индикатор метода актора имеет смысл только для тех методов, которые не используются как сообщения - т.к. сообщения имеют лишь входящие данные. Поэтому, можете использовать channeling pattern - метод, который имеет на выходе индикатор состояния вызывается внутри метода, который может быть вызван при помощи сообщения. Таким образом, "главный" актор будет посылать нужному актору эти сообщения на исполнение, и таким образом внутри них будет вызываться вложенный метод + обрабатываться (отслыться в качестве отчета) индикатор выполнения.
Надеюсь, что не очень запутанно попытался объяснить...
Мы делили апельсин - много наших полегло...
-
IvanLis
- guru
- Сообщения: 5467
- Зарегистрирован: 02 дек 2009, 17:44
- Награды: 7
- Версия LabVIEW: 2015, 2016
- Откуда: СССР
- Благодарил (а): 28 раз
- Поблагодарили: 87 раз
Re: Actor Framework
Уважаемые знатоки Actor Framework, подскажите как обойти следующую проблему во взаимодействии Акторов.
Имеется два Актора:
1. Позволяет задать диапазон выбранных значений (ползунок) и отображает результаты SQL запроса из БД.
2. Принимает от первого диапазон значений, который запросить из БД, запрашивает их, сворачивает и отправляет их для отображения первому Актору.
Все как-бы нормально, но БД на сервере и запрос выполняется некоторое время. Ползунок двигается последовательно, и например мне нужно выбрать данные в диапазоне 0..10. Я начинаю двигать ползунок от 0 к 10, а и Актор-1 начинает посылать сообщения Актору-2:
- диапазон 0..1
- диапазон 0..2
...
- диапазон 0..10
Актор-2 начинает их обрабатывать, но с сильным запаздыванием
в результате, необходимая мне информация появляется с большой задержкой
Если для этих целей использовать Queue, то я бы перепахал очередь, и в Акторе-2 взял последнее сообщение с указанием диапазона, а остальные удалил, т.е. получается, что все запросы содержащие диапазон игнорировал, за исключением последнего (самого актуального).
Можно ли как-то выполнять фильтрацию Message посылаемых/принимаемых Акторами?
Имеется два Актора:
1. Позволяет задать диапазон выбранных значений (ползунок) и отображает результаты SQL запроса из БД.
2. Принимает от первого диапазон значений, который запросить из БД, запрашивает их, сворачивает и отправляет их для отображения первому Актору.
Все как-бы нормально, но БД на сервере и запрос выполняется некоторое время. Ползунок двигается последовательно, и например мне нужно выбрать данные в диапазоне 0..10. Я начинаю двигать ползунок от 0 к 10, а и Актор-1 начинает посылать сообщения Актору-2:
- диапазон 0..1
- диапазон 0..2
...
- диапазон 0..10
Актор-2 начинает их обрабатывать, но с сильным запаздыванием
в результате, необходимая мне информация появляется с большой задержкой
![suicide :suicide:](./images/smilies/icon_suicide.gif)
Если для этих целей использовать Queue, то я бы перепахал очередь, и в Акторе-2 взял последнее сообщение с указанием диапазона, а остальные удалил, т.е. получается, что все запросы содержащие диапазон игнорировал, за исключением последнего (самого актуального).
Можно ли как-то выполнять фильтрацию Message посылаемых/принимаемых Акторами?
Знание нескольких принципов освобождает от знания многих фактов!
Правила форума
Как добавить в сообщение картинку или файл
Конвертация / версий (форматов) VI
Как правильно задать вопрос...
Правила форума
Как добавить в сообщение картинку или файл
Конвертация / версий (форматов) VI
Как правильно задать вопрос...
-
Kosist
- expert
- Сообщения: 1236
- Зарегистрирован: 21 фев 2011, 23:44
- Награды: 2
- Версия LabVIEW: 2013-2020
- Благодарил (а): 23 раза
- Поблагодарили: 30 раз
- Контактная информация:
Re: Actor Framework
Фильтрацию получаемых методов можно делать в методе Receive Message.vi. Но это Вам не поможет - т.к. актор не будет знать, что его ждет еще с десяток сообщений...
Это не проблема актор фреймворка - как Вы написали, если бы сообщения отсылались обычной очередью, то их тоже было бы много в буфере, но можно было бы выбрать лишь последнюю (что означает, что лучше потом бы было использовать Notifier, но это сейчас роли не играет).
Это можно решить 2-мя способами.
1. Актор-1 имеет "внутренний" буфер сообщений, и флаг-состояние: сообщение послано/ожидается ответ; и ответ был получен. Актор-1 вначале отсылает сообщения по изменению ползунка самому себе, и сохраняет их в собственный буфер. Если буфер пустой, то сообщение отсылается актору-2, и флаг-состояние устанавливается "в режим ожидания ответа". Если ответ не был получен, но в буфер пришло еще одно сообщение - оно просто сохраняется в буфер. Когда актор-2 посылает ответ назад актору-1, флаг-состояние изменяется на "ответ получен", проверяется буфер сообщений - выбирается последнее, и отсылается.
2. Актор-2, когда получает сообщение от актора-1, вначале отсылает его во вспомогательный цикл в Actor Core, где собственно и происходит коммуникация с базой данных. Данные во вспомогательный цикл можут отсылаться при помощи очереди - и таким образом, в цикле можно прочитать потом все комманды, и выполнить лишь последнюю (ну или тот же Notifier). Я бы рекомендовал этот вариант,т.к. он более "актор-ориентирован". Актор должен всегда быть отзывчивым - он не должен "застревать" при обработке сообщений. Т.к. пока актор выполняет сообщение, ему можно отсылать другие сообщения, но он их не может прочитать - сообщения будут прочитаны из очереди на очередной итерации while цикла в ядре актора. Поэтому NI рекомендует делегировать подобные "долгоиграющие" сообщения впомогательному циклу (helper loop) который крутится паралельно в Actor Core, и не блокирует обработку поступающих сообщений.
Это не проблема актор фреймворка - как Вы написали, если бы сообщения отсылались обычной очередью, то их тоже было бы много в буфере, но можно было бы выбрать лишь последнюю (что означает, что лучше потом бы было использовать Notifier, но это сейчас роли не играет).
Это можно решить 2-мя способами.
1. Актор-1 имеет "внутренний" буфер сообщений, и флаг-состояние: сообщение послано/ожидается ответ; и ответ был получен. Актор-1 вначале отсылает сообщения по изменению ползунка самому себе, и сохраняет их в собственный буфер. Если буфер пустой, то сообщение отсылается актору-2, и флаг-состояние устанавливается "в режим ожидания ответа". Если ответ не был получен, но в буфер пришло еще одно сообщение - оно просто сохраняется в буфер. Когда актор-2 посылает ответ назад актору-1, флаг-состояние изменяется на "ответ получен", проверяется буфер сообщений - выбирается последнее, и отсылается.
2. Актор-2, когда получает сообщение от актора-1, вначале отсылает его во вспомогательный цикл в Actor Core, где собственно и происходит коммуникация с базой данных. Данные во вспомогательный цикл можут отсылаться при помощи очереди - и таким образом, в цикле можно прочитать потом все комманды, и выполнить лишь последнюю (ну или тот же Notifier). Я бы рекомендовал этот вариант,т.к. он более "актор-ориентирован". Актор должен всегда быть отзывчивым - он не должен "застревать" при обработке сообщений. Т.к. пока актор выполняет сообщение, ему можно отсылать другие сообщения, но он их не может прочитать - сообщения будут прочитаны из очереди на очередной итерации while цикла в ядре актора. Поэтому NI рекомендует делегировать подобные "долгоиграющие" сообщения впомогательному циклу (helper loop) который крутится паралельно в Actor Core, и не блокирует обработку поступающих сообщений.
Мы делили апельсин - много наших полегло...
-
taras_33
- professional
- Сообщения: 392
- Зарегистрирован: 31 окт 2009, 18:25
- Награды: 1
- Версия LabVIEW: 2019
- Поблагодарили: 13 раз
- Контактная информация:
Re: Actor Framework
Я бы попробовал поиграть с mouse up and mouse down events в первом актёре. Скажем диапазон задаётся одним ползунком. Кнопку нажали - послал сообщение себе и ничего не отсылая ждём события mouse up. Событие произошло отсылаем себе второе значение и полученную разницу отсылаем второму актеру. Если ползунков два, то используем два события mouse up, каждое на свой ползунок.в Акторе-2 взял последнее сообщение с указанием диапазона, а остальные удалил, т.е. получается, что все запросы содержащие диапазон игнорировал, за исключением последнего (самого актуального).
Или я чего-то не так понял?
Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots.
So far, the Universe is winning!
So far, the Universe is winning!
-
IvanLis
- guru
- Сообщения: 5467
- Зарегистрирован: 02 дек 2009, 17:44
- Награды: 7
- Версия LabVIEW: 2015, 2016
- Откуда: СССР
- Благодарил (а): 28 раз
- Поблагодарили: 87 раз
Re: Actor Framework
Нужно попробовать предложения Kosist, пока обошел используя UserEvent.
На самом деле сейчас ситуация несколько иная, я привел пример из одной из предыдущих задач.
Сейчас необходимо отрисовывать некую 3D модель реального устройства. С датчиков поступает информация о положении модели и ее элементов, мне нужно что бы 3D модель отражала реальное положение.
Информация с датчиков поступает несколько быстрее, чем модель успевает перерисовываться.
Можно было бы отображать например каждый 10 элемент, но скорости поступления и отрисовки не постоянны.
По этому я и беру последнее - актуальное значение и отображаю его.
На самом деле сейчас ситуация несколько иная, я привел пример из одной из предыдущих задач.
Сейчас необходимо отрисовывать некую 3D модель реального устройства. С датчиков поступает информация о положении модели и ее элементов, мне нужно что бы 3D модель отражала реальное положение.
Информация с датчиков поступает несколько быстрее, чем модель успевает перерисовываться.
Можно было бы отображать например каждый 10 элемент, но скорости поступления и отрисовки не постоянны.
По этому я и беру последнее - актуальное значение и отображаю его.
Знание нескольких принципов освобождает от знания многих фактов!
Правила форума
Как добавить в сообщение картинку или файл
Конвертация / версий (форматов) VI
Как правильно задать вопрос...
Правила форума
Как добавить в сообщение картинку или файл
Конвертация / версий (форматов) VI
Как правильно задать вопрос...
-
- professor
- Сообщения: 3406
- Зарегистрирован: 31 июл 2011, 23:05
- Награды: 2
- Версия LabVIEW: 12-18
- Благодарил (а): 49 раз
- Поблагодарили: 176 раз
- Контактная информация:
Re: Actor Framework
Снова взываю к помощи знатоков.
Есть метод актора. И акторов два клона. И метод подозрительно долго работает, хотя всего лишь обновляет по одному элементу в двух массивах (ну да, массивы не маленькие, но всё же, не 1,2 сек же).
Пока не понимаю, почему торможит, призадумался. А почему методы акторов не клоновые? Если акторы клонируются, они всё равно не работают "параллельно"?
Есть метод актора. И акторов два клона. И метод подозрительно долго работает, хотя всего лишь обновляет по одному элементу в двух массивах (ну да, массивы не маленькие, но всё же, не 1,2 сек же).
Пока не понимаю, почему торможит, призадумался. А почему методы акторов не клоновые? Если акторы клонируются, они всё равно не работают "параллельно"?
-
Kosist
- expert
- Сообщения: 1236
- Зарегистрирован: 21 фев 2011, 23:44
- Награды: 2
- Версия LabVIEW: 2013-2020
- Благодарил (а): 23 раза
- Поблагодарили: 30 раз
- Контактная информация:
Re: Actor Framework
А исполняемые методы реетрантные? Если нет, то тогда они не будут исполняться паралельно. Actor Core.vi реетрантный, методы для сообщений - Send ..., Do тоже реетрантные. Но сами методы нужно конфигурировать вручную.
Мы делили апельсин - много наших полегло...
-
- professor
- Сообщения: 3406
- Зарегистрирован: 31 июл 2011, 23:05
- Награды: 2
- Версия LabVIEW: 12-18
- Благодарил (а): 49 раз
- Поблагодарили: 176 раз
- Контактная информация:
Re: Actor Framework
Методы не реентрантные, в этом и вопрос: почему по умолчанию они обычные, хотя акторы предполагают клонируемость
-
Kosist
- expert
- Сообщения: 1236
- Зарегистрирован: 21 фев 2011, 23:44
- Награды: 2
- Версия LabVIEW: 2013-2020
- Благодарил (а): 23 раза
- Поблагодарили: 30 раз
- Контактная информация:
Re: Actor Framework
Потому что акторы - это просто классы. Вы ведь создаете их методы как для обычных классов - ПКМ -> VI/Static dispatch/Dynamic dispatch, и т.д. И поэтому, их методы тоже "обычные".Artem.spb писал(а):Методы не реентрантные, в этом и вопрос: почему по умолчанию они обычные, хотя акторы предполагают клонируемость
Ну, и клонируемость не есть главная идея акторов. Асинхронность - да, использование "фишек" ООП - да, но клонируемость в явном виде нет. Это уже конкретный случай, когда нужно запускать на исполнение множественное число инстанций актора; а не общий. В общем случае - у Вас много разных акторов, которые исполняются асинхронно и независимо друг от друга, "общаясь" при помощи сообщений.
Мы делили апельсин - много наших полегло...
- jane_wild
- master
- Сообщения: 461
- Зарегистрирован: 30 июн 2016, 02:11
- Версия LabVIEW: 2020
- Благодарил (а): 84 раза
- Поблагодарили: 15 раз
- Контактная информация:
Re: Actor Framework
Ребята простой вопрос.
Стандартная ситуация - Один Actor посылает другому Actor сообщение с данными для обработки. Второй Actor не успевает их обрабатывать, в результате накапливается очередь, что приводит к нежелательным эффектам, например задержкам на выполнение комманд...
Я понимаю, что нужно реже отсылать, но вопрос в другом
Возможно ли как то получать информацию о количестве сообщений в очереди, от кого они были посланы? Может вообще можно эту самую очередь очистить?
Спасибо.
Стандартная ситуация - Один Actor посылает другому Actor сообщение с данными для обработки. Второй Actor не успевает их обрабатывать, в результате накапливается очередь, что приводит к нежелательным эффектам, например задержкам на выполнение комманд...
Я понимаю, что нужно реже отсылать, но вопрос в другом
Возможно ли как то получать информацию о количестве сообщений в очереди, от кого они были посланы? Может вообще можно эту самую очередь очистить?
Спасибо.