Как получить доступ к состоянию актера на основе классов из контекста блокировки (C ++ Actor Framework)

Я хотел бы получить доступ к состоянию актера на основе класса из контекста блокировки, выставляя текущее состояние с помощью обычных методов класса. Какой лучший подход? Я могу думать о трех основных направлениях:

  1. Классовые актеры не должны раскрывать свое состояние, кроме как посредством передачи сообщений (т.е. я делаю что-то не так с самого начала)
  2. Метод (ы) класса должен использовать scoped_actor отправить сообщение актеру на основе класса и вернуть ответ.
  3. Метод (ы) класса должен обходить структуру субъекта и просто обращаться к переменной-члену, содержащей состояние.

Я попытался использовать подход № 2, но, хотя и выяснил, как добавить ключевое слово ‘mutable’ для изменения захваченной переменной, я не смог успешно отложить возврат метода до тех пор, пока захваченная переменная не может быть установлена ​​без создания тупика.

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

using size_atom = atom_constant<atom("size")>;
using done_atom = atom_constant<atom("done")>;
using a_type = typed_actor<
replies_to<int>::with<void>,
replies_to<size_atom>::with<size_t>,
replies_to<done_atom>::with<void>>;

class A : public a_type::base
{
public:
size_t size_direct_access()
{
return this->m_values.size();
}

size_t size_protected_access()
{
lock_guard<mutex> lock(this->m_mutex);
return this->m_values.size();
}
protected:
behavior_type make_behavior() override
{
return
{
[this](int value)
{
lock_guard<mutex> lock(this->m_mutex);
this->m_values.push_back(value);
},
[this](size_atom) -> size_t
{
lock_guard<mutex> lock(this->m_mutex);
return this->m_values.size();
},
[this](done_atom)
{
this->quit();
}
};
}
private:
vector<int> m_values;
mutex m_mutex;
};

void tester()
{
a_type testeeActor = spawn_typed<A, detached>();
abstract_actor* abstractActor = actor_cast<abstract_actor*, a_type>(testeeActor);
A* a = dynamic_cast<A*>(abstractActor);
scoped_actor self;
self->sync_send(testeeActor, 5).await(
[a, testeeActor, &self]()
{
size_t direct_access = a->size_direct_access();
size_t protected_access = a->size_protected_access();
aout(self) << "Direct: " << direct_access << " Protected: " << protected_access << endl;

self->sync_send(testeeActor, 3).await(
[a, testeeActor, &self]()
{
size_t direct_access = a->size_direct_access();
size_t protected_access = a->size_protected_access();
aout(self) << "Direct: " << direct_access << " Protected: " << protected_access << endl;

self->sync_send(testeeActor, 1).await(
[a, testeeActor, &self]()
{
size_t direct_access = a->size_direct_access();
size_t protected_access = a->size_protected_access();
aout(self) << "Direct: " << direct_access << " Protected: " << protected_access << endl;

self->sync_send(testeeActor, done_atom::value);
});
});
});
}

int main()
{
cout << "Spawning actors" << endl;
tester();
cout << "Awaiting all actors done" << endl;
await_all_actors_done();
cout << "Shutdown" << endl;
shutdown();
cout << "Press Enter to continue" << endl;
cin.get();
}

3

Решение

Вы отвечаете на свой вопрос в самом начале:

Актеры на основе классов не должны раскрывать свое состояние, кроме как посредством передачи сообщений (то есть я делаю что-то не так с самого начала)

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

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

Повышение уровня: если вам нужен доступ к данным актера, вам, вероятно, следует пересмотреть дизайн своей программы.

3

Другие решения

Других решений пока нет …