Hazelcast C++ Client
Future.h
1 /*
2  * Copyright (c) 2008-2017, Hazelcast, Inc. All Rights Reserved.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #ifndef HAZELCAST_CLIENT_FUTURE_H_
17 #define HAZELCAST_CLIENT_FUTURE_H_
18 
19 #include <stdint.h>
20 #include <memory>
21 #include <assert.h>
22 
23 #include "hazelcast/client/connection/CallFuture.h"
24 #include "hazelcast/client/serialization/pimpl/SerializationService.h"
25 #include "hazelcast/client/connection/CallPromise.h"
26 #include "hazelcast/client/TypedData.h"
27 #include "hazelcast/client/protocol/ClientMessage.h"
28 
29 #if defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64)
30 #pragma warning(push)
31 #pragma warning(disable: 4251) //for dll export
32 #endif
33 
34 namespace hazelcast {
35  namespace client {
36  class HAZELCAST_API future_status {
37  public:
38  future_status(int value) : value(value) { }
39 
40  enum enum_type {
41  ready,
42  timeout
43  };
44 
45  friend bool operator==(future_status lhs, future_status rhs) {
46  return enum_type(lhs.value) == enum_type(rhs.value);
47  }
48 
49  friend bool operator==(future_status lhs, enum_type rhs) { return enum_type(lhs.value) == rhs; }
50 
51  friend bool operator==(enum_type lhs, future_status rhs) { return lhs == enum_type(rhs.value); }
52 
53  friend bool operator!=(future_status lhs, future_status rhs) {
54  return enum_type(lhs.value) != enum_type(rhs.value);
55  }
56 
57  friend bool operator!=(future_status lhs, enum_type rhs) { return enum_type(lhs.value) != rhs; }
58 
59  friend bool operator!=(enum_type lhs, future_status rhs) { return lhs != enum_type(rhs.value); }
60 
61  friend bool operator<(future_status lhs, future_status rhs) {
62  return enum_type(lhs.value) < enum_type(rhs.value);
63  }
64 
65  friend bool operator<(future_status lhs, enum_type rhs) { return enum_type(lhs.value) < rhs; }
66 
67  friend bool operator<(enum_type lhs, future_status rhs) { return lhs < enum_type(rhs.value); }
68 
69  friend bool operator<=(future_status lhs, future_status rhs) {
70  return enum_type(lhs.value) <= enum_type(rhs.value);
71  }
72 
73  friend bool operator<=(future_status lhs, enum_type rhs) { return enum_type(lhs.value) <= rhs; }
74 
75  friend bool operator<=(enum_type lhs, future_status rhs) { return lhs <= enum_type(rhs.value); }
76 
77  friend bool operator>(future_status lhs, future_status rhs) {
78  return enum_type(lhs.value) > enum_type(rhs.value);
79  }
80 
81  friend bool operator>(future_status lhs, enum_type rhs) { return enum_type(lhs.value) > rhs; }
82 
83  friend bool operator>(enum_type lhs, future_status rhs) { return lhs > enum_type(rhs.value); }
84 
85  friend bool operator>=(future_status lhs, future_status rhs) {
86  return enum_type(lhs.value) >= enum_type(rhs.value);
87  }
88 
89  friend bool operator>=(future_status lhs, enum_type rhs) { return enum_type(lhs.value) >= rhs; }
90 
91  friend bool operator>=(enum_type lhs, future_status rhs) { return lhs >= enum_type(rhs.value); }
92 
93  private:
94  int value;
95  };
96 
97  namespace exception {
98  class HAZELCAST_API FutureUninitialized : public IException {
99  public:
100  FutureUninitialized(const std::string &source, const std::string &message) : IException(source,
101  message) { }
102  };
103  }
104 
112  template<typename V>
113  class Future {
114  public:
115  typedef std::auto_ptr<serialization::pimpl::Data> (*Decoder)(protocol::ClientMessage &response);
116 
120  Future(connection::CallFuture &callFuture,
121  serialization::pimpl::SerializationService &serializationService,
122  Decoder decoder) : callFuture(new connection::CallFuture(callFuture)),
123  serializationService(serializationService), decoderFunction(decoder) {
124  }
125 
131  Future(const Future &movedFuture) : callFuture(movedFuture.callFuture),
132  serializationService(movedFuture.serializationService),
133  decoderFunction(movedFuture.decoderFunction) {
134  }
135 
142  Future &operator=(const Future &movedFuture) {
143  this->callFuture = movedFuture.callFuture;
144  this->decoderFunction = movedFuture.decoderFunction;
145  return *this;
146  }
147 
148  virtual ~Future() {
149  }
150 
167  std::auto_ptr<V> get() {
168  if (!callFuture.get()) {
169  throw exception::FutureUninitialized("Future::get", "Future needs to be initialized. "
170  "It may have been moved from.");
171  }
172 
173  std::auto_ptr<protocol::ClientMessage> responseMsg = callFuture->get();
174 
175  assert(responseMsg.get());
176 
177  callFuture.reset();
178 
179  std::auto_ptr<serialization::pimpl::Data> response = decoderFunction(*responseMsg);
180 
181  std::auto_ptr<V> result = serializationService.toObject<V>(response.get());
182 
183  return result;
184  }
185 
197  future_status wait_for(int64_t timeoutInMilliseconds) const {
198  if (!callFuture.get()) {
199  throw exception::FutureUninitialized("Future::get", "Future needs to be initialized.");
200  }
201 
202  return callFuture->waitFor(timeoutInMilliseconds) ? future_status::ready : future_status::timeout;
203  }
204 
211  void wait() const {
212  wait_for(INT64_MAX);
213  }
214 
222  bool valid() const {
223  return callFuture.get() != NULL;
224  }
225 
226  private:
227  mutable std::auto_ptr<connection::CallFuture> callFuture;
228  serialization::pimpl::SerializationService &serializationService;
229  Decoder decoderFunction;
230  };
231 
235  template<>
236  class Future<TypedData> {
237  public:
238  typedef std::auto_ptr<serialization::pimpl::Data> (*Decoder)(protocol::ClientMessage &response);
239 
243  Future(connection::CallFuture &callFuture,
244  serialization::pimpl::SerializationService &serializationService,
245  Decoder decoder) : callFuture(new connection::CallFuture(callFuture)),
246  serializationService(serializationService), decoderFunction(decoder) {
247  }
248 
254  Future(const Future &movedFuture) : callFuture(movedFuture.callFuture),
255  serializationService(movedFuture.serializationService),
256  decoderFunction(movedFuture.decoderFunction) {
257  }
258 
265  Future &operator=(const Future &movedFuture) {
266  this->callFuture = movedFuture.callFuture;
267  this->decoderFunction = movedFuture.decoderFunction;
268  return *this;
269  }
270 
271  virtual ~Future() {
272  }
273 
290  TypedData get() {
291  if (!callFuture.get()) {
292  throw exception::FutureUninitialized("Future::get", "Future needs to be initialized. "
293  "It may have been moved from.");
294  }
295 
296  std::auto_ptr<protocol::ClientMessage> responseMsg = callFuture->get();
297 
298  assert(responseMsg.get());
299 
300  callFuture.reset();
301 
302  std::auto_ptr<serialization::pimpl::Data> response = decoderFunction(*responseMsg);
303 
304  return TypedData(response, serializationService);
305  }
306 
318  future_status wait_for(int64_t timeoutInMilliseconds) const {
319  if (!callFuture.get()) {
320  throw exception::FutureUninitialized("Future::get", "Future needs to be initialized.");
321  }
322 
323  return callFuture->waitFor(timeoutInMilliseconds) ? future_status::ready : future_status::timeout;
324  }
325 
332  void wait() const {
333  wait_for(INT64_MAX);
334  }
335 
343  bool valid() const {
344  return callFuture.get() != NULL;
345  }
346 
347  private:
348  mutable std::auto_ptr<connection::CallFuture> callFuture;
349  serialization::pimpl::SerializationService &serializationService;
350  Decoder decoderFunction;
351  };
352  }
353 }
354 
355 #if defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64)
356 #pragma warning(pop)
357 #endif
358 
359 #endif /* HAZELCAST_CLIENT_FUTURE_H_ */
Future(connection::CallFuture &callFuture, serialization::pimpl::SerializationService &serializationService, Decoder decoder)
This constructor is only for internal use!!!!
Definition: Future.h:243
Future(const Future &movedFuture)
This is actually a move constructor Constructs a Future with the shared state of movedFuture using mo...
Definition: Future.h:254
Base class for all exception originated from Hazelcast methods.
Definition: IException.h:49
future_status wait_for(int64_t timeoutInMilliseconds) const
Waits for the result to become available.
Definition: Future.h:318
Future & operator=(const Future &movedFuture)
Assigns the contents of another future object.
Definition: Future.h:265
void wait() const
Blocks until the result becomes available.
Definition: Future.h:332
Definition: Future.h:36
bool valid() const
Checks if the future refers to a shared state.
Definition: Future.h:343
This is a unique Future.
Definition: Future.h:113
bool valid() const
Checks if the future refers to a shared state.
Definition: Future.h:222
Future(connection::CallFuture &callFuture, serialization::pimpl::SerializationService &serializationService, Decoder decoder)
This constructor is only for internal use!!!!
Definition: Future.h:120
void wait() const
Blocks until the result becomes available.
Definition: Future.h:211
future_status wait_for(int64_t timeoutInMilliseconds) const
Waits for the result to become available.
Definition: Future.h:197
Definition: MapEntryView.h:32
Future & operator=(const Future &movedFuture)
Assigns the contents of another future object.
Definition: Future.h:142
Future(const Future &movedFuture)
This is actually a move constructor Constructs a Future with the shared state of movedFuture using mo...
Definition: Future.h:131
TypedData class is a wrapper class for the serialized binary data.
Definition: TypedData.h:40