swift
dupleximpl.cpp
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: Copyright (C) 2020 swift Project Community / Contributors
2 // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-swift-pilot-client-1
3 
5 
7 
8 #include "misc/dbusserver.h"
9 #include "misc/identifier.h"
11 #include "misc/variantlist.h"
12 #include "misc/verify.h"
13 
14 namespace swift::misc::shared_state::dbus
15 {
16  CDuplex::CDuplex(CHub *hub, const CIdentifier &client, CDBusServer *server, QObject *parent)
17  : IDuplex(parent), m_hub(hub)
18  {
19  if (server) { server->addObject(client.toDBusObjectPath(SWIFT_MISC_DUPLEX_PATH_ROOT), this); }
20  }
21 
23  {
24  while (!m_subscriptions.isEmpty())
25  {
26  const auto channel = m_subscriptions.firstKey(); // explicit copy because a reference would dangle
27  setSubscription(channel, {});
28  }
29  }
30 
31  void CDuplex::postEvent(const QString &channel, const CVariant &param)
32  {
33  for (auto client : m_hub->clients())
34  {
35  if (client != this && client->m_subscriptions.value(channel).matches(param))
36  {
37  emit client->eventPosted(channel, param);
38  }
39  }
40  }
41 
42  void CDuplex::setSubscription(const QString &channel, const CVariantList &filters)
43  {
44  if (filters.isEmpty()) { m_subscriptions.remove(channel); }
45  else { m_subscriptions.insert(channel, filters); }
46 
47  for (auto client : m_hub->clients())
48  {
49  if (client != this) { client->requestPeerSubscriptions(channel); }
50  }
51  }
52 
54  {
55  QSet<QString> channels;
56  for (const auto &client : m_hub->clients())
57  {
58  if (client != this)
59  {
60  const auto &keys = client->m_subscriptions.keys();
61  const QSet subscriptions(keys.begin(), keys.end());
62  channels.unite(subscriptions);
63  }
64  }
65  for (const auto &channel : channels) { requestPeerSubscriptions(channel); }
66  }
67 
68  void CDuplex::requestPeerSubscriptions(const QString &channel)
69  {
70  CVariantList filters;
71  for (auto peer : m_hub->clients())
72  {
73  if (peer != this) { filters.push_back(peer->m_subscriptions.value(channel)); }
74  }
75 
76  emit peerSubscriptionsReceived(channel, filters);
77  }
78 
79  void CDuplex::submitRequest(const QString &channel, const CVariant &param, quint32 token)
80  {
81  for (auto handler : m_hub->clients())
82  {
83  if (handler != this && handler->m_handlingChannels.contains(channel))
84  {
85  doAfter(handler->receiveRequest(channel, param), this,
86  [this, channel, token](QFuture<CVariant> future) {
87  emit this->replyReceived(channel, future.result(), token);
88  });
89  return;
90  }
91  }
92  }
93 
94  void CDuplex::advertise(const QString &channel) { m_handlingChannels.insert(channel); }
95 
96  void CDuplex::withdraw(const QString &channel) { m_handlingChannels.remove(channel); }
97 } // namespace swift::misc::shared_state::dbus
Custom DBusServer.
Definition: dbusserver.h:34
void addObject(const QString &name, QObject *object)
Add a QObject to be exposed via DBus.
Definition: dbusserver.cpp:226
Value object encapsulating information identifying a component of a modular distributed swift process...
Definition: identifier.h:29
QString toDBusObjectPath(const QString &root={}) const
Produces a DBus object path from the identifier.
Definition: identifier.cpp:131
void push_back(const T &value)
Appends an element at the end of the sequence.
Definition: sequence.h:305
bool isEmpty() const
Synonym for empty.
Definition: sequence.h:285
Wrapper around QVariant which provides transparent access to CValueObject methods of the contained ob...
Definition: variant.h:66
Value object encapsulating a list of variants.
Definition: variantlist.h:29
virtual void postEvent(const QString &channel, const swift::misc::CVariant &param)
Client posts an event to the server.
Definition: dupleximpl.cpp:31
virtual void advertise(const QString &channel)
Client advertises that it can handle requests for the given channel.
Definition: dupleximpl.cpp:94
virtual void requestPeerSubscriptions()
Client requests to be notified of all other clients' subscriptions.
Definition: dupleximpl.cpp:53
CDuplex(CHub *hub, const CIdentifier &client, CDBusServer *server, QObject *parent=nullptr)
Constructor.
Definition: dupleximpl.cpp:16
virtual void setSubscription(const QString &channel, const swift::misc::CVariantList &filters)
Client announces its subscription to an event channel.
Definition: dupleximpl.cpp:42
virtual void submitRequest(const QString &channel, const swift::misc::CVariant &param, quint32 token)
Client submits a request to the server. Reply is returned via a future.
Definition: dupleximpl.cpp:79
virtual void withdraw(const QString &channel)
Client advertises that it can no longer handle requests for the given channel.
Definition: dupleximpl.cpp:96
Server side implementation of IHub.
Definition: hubimpl.h:27
const auto & clients() const
Returns a range containing all duplex objects.
Definition: hubimpl.h:39
Abstract interface for the spoke in a star topology.
Definition: duplex.h:36
void peerSubscriptionsReceived(const QString &channel, const swift::misc::CVariantList &filters)
Server has notified the client that other clients' event subscriptions have changed.
#define SWIFT_MISC_DUPLEX_PATH_ROOT
DBus object path root for sharedstate hub.
Definition: duplex.h:22
void doAfter(QFuture< T > future, QObject *context, F &&func)
Connect a slot or function to be invoked in the given context when a QFuture is finished.
Definition: promise.h:59