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

KDE's Doxygen guidelines are available online.