Akonadi

connection.h
1 /***************************************************************************
2  * SPDX-FileCopyrightText: 2006 Till Adam <[email protected]> *
3  * *
4  * SPDX-License-Identifier: LGPL-2.0-or-later *
5  ***************************************************************************/
6 
7 #ifndef AKONADI_CONNECTION_H
8 #define AKONADI_CONNECTION_H
9 
10 #include <QThread>
11 #include <QTimer>
12 #include <QLocalSocket>
13 #include <QElapsedTimer>
14 
15 #include "akonadi.h"
16 #include "akthread.h"
17 #include "entities.h"
18 #include "global.h"
19 #include "commandcontext.h"
20 #include "tracer.h"
21 
22 #include <private/protocol_p.h>
23 #include <private/datastream_p_p.h>
24 
25 #include <memory>
26 
27 namespace Akonadi
28 {
29 namespace Server
30 {
31 
32 class Handler;
33 class Response;
34 class DataStore;
35 class Collection;
36 
40 class Connection : public AkThread
41 {
42  Q_OBJECT
43 public:
44  explicit Connection(quintptr socketDescriptor, AkonadiServer &akonadi);
45  ~Connection() override;
46 
47  virtual DataStore *storageBackend();
48 
49  const CommandContext &context() const;
50  void setContext(const CommandContext &context);
51 
52  AkonadiServer &akonadi() const { return m_akonadi; }
53 
57  bool isOwnerResource(const PimItem &item) const;
58  bool isOwnerResource(const Collection &collection) const;
59 
60  void setSessionId(const QByteArray &id);
61  QByteArray sessionId() const;
62 
64  bool verifyCacheOnRetrieval() const;
65 
66  Protocol::CommandPtr readCommand();
67 
68  void setState(ConnectionState state);
69 
70  template<typename T>
71  inline typename std::enable_if<std::is_base_of<Protocol::Command, T>::value>::type
72  sendResponse(T &&response);
73 
74  void sendResponse(qint64 tag, const Protocol::CommandPtr &response);
75 
76 Q_SIGNALS:
77  void disconnected();
78  void connectionClosing();
79 
80 protected Q_SLOTS:
81  void handleIncomingData();
82 
83  void slotConnectionIdle();
84  void slotSocketDisconnected();
85  void slotSendHello();
86 
87 protected:
88  Connection(AkonadiServer &akonadi); // used for testing
89 
90  void init() override;
91  void quit() override;
92 
93  std::unique_ptr<Handler> findHandlerForCommand(Protocol::Command::Type cmd);
94 
95  qint64 currentTag() const;
96 
97 protected:
98  quintptr m_socketDescriptor = {};
99  AkonadiServer &m_akonadi;
100  std::unique_ptr<QLocalSocket> m_socket;
101  std::unique_ptr<Handler> m_currentHandler;
102  std::unique_ptr<QTimer> m_idleTimer;
103 
104  ConnectionState m_connectionState = NonAuthenticated;
105 
106  mutable DataStore *m_backend = nullptr;
107  QList<QByteArray> m_statusMessageQueue;
108  QString m_identifier;
109  QByteArray m_sessionId;
110  bool m_verifyCacheOnRetrieval = false;
111  CommandContext m_context;
112 
113  QElapsedTimer m_time;
114  qint64 m_totalTime = 0;
115  QHash<QString, qint64> m_totalTimeByHandler;
116  QHash<QString, qint64> m_executionsByHandler;
117 
118  bool m_connectionClosing = false;
119 
120 private:
121  void parseStream(const Protocol::CommandPtr &cmd);
122  template<typename T>
123  inline typename std::enable_if<std::is_base_of<Protocol::Command, T>::value>::type
124  sendResponse(qint64 tag, T &&response);
125 
127  void startTime();
128  void stopTime(const QString &identifier);
129  void reportTime() const;
130  bool m_reportTime = false;
131 
132 };
133 
134 template<typename T>
135 inline typename std::enable_if<std::is_base_of<Protocol::Command, T>::value>::type
136 Connection::sendResponse(T &&response)
137 {
138  sendResponse<T>(currentTag(), std::move(response));
139 }
140 
141 template<typename T>
142 inline typename std::enable_if<std::is_base_of<Protocol::Command, T>::value>::type
143 Connection::sendResponse(qint64 tag, T &&response)
144 {
145  if (m_akonadi.tracer().currentTracer() != QLatin1String("null")) {
146  m_akonadi.tracer().connectionOutput(m_identifier, tag, response);
147  }
148  Protocol::DataStream stream(m_socket.get());
149  stream << tag;
150  stream << std::move(response);
151  stream.flush();
152  if (!m_socket->waitForBytesWritten()) {
153  if (m_socket->state() == QLocalSocket::ConnectedState) {
154  throw ProtocolException("Server write timeout");
155  } else {
156  // The client has disconnected before we managed to send our response,
157  // which is not an error
158  }
159  }
160 }
161 
162 } // namespace Server
163 } // namespace Akonadi
164 
165 #endif
bool verifyCacheOnRetrieval() const
Returns true if permanent cache verification is enabled.
Represents a collection of PIM items.
Definition: collection.h:63
bool isOwnerResource(const PimItem &item) const
Returns true if this connection belongs to the owning resource of item.
Q_SIGNALSQ_SIGNALS
Q_OBJECTQ_OBJECT
Helper integration between Akonadi and Qt.
This class handles all the database access.
Definition: datastore.h:95
Q_SLOTSQ_SLOTS
An Connection represents one connection of a client to the server.
Definition: connection.h:40
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Fri Jul 3 2020 23:15:51 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.