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 
28 #if defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64)
29 #pragma warning(push)
30 #pragma warning(disable: 4251) //for dll export
31 #endif
32 
33 namespace hazelcast {
34  namespace client {
35  class HAZELCAST_API future_status {
36  public:
37  future_status(int value) : value(value) { }
38 
39  enum enum_type {
40  ready,
41  timeout
42  };
43 
44  friend bool operator==(future_status lhs, future_status rhs) {
45  return enum_type(lhs.value) == enum_type(rhs.value);
46  }
47 
48  friend bool operator==(future_status lhs, enum_type rhs) { return enum_type(lhs.value) == rhs; }
49 
50  friend bool operator==(enum_type lhs, future_status rhs) { return lhs == enum_type(rhs.value); }
51 
52  friend bool operator!=(future_status lhs, future_status rhs) {
53  return enum_type(lhs.value) != enum_type(rhs.value);
54  }
55 
56  friend bool operator!=(future_status lhs, enum_type rhs) { return enum_type(lhs.value) != rhs; }
57 
58  friend bool operator!=(enum_type lhs, future_status rhs) { return lhs != enum_type(rhs.value); }
59 
60  friend bool operator<(future_status lhs, future_status rhs) {
61  return enum_type(lhs.value) < enum_type(rhs.value);
62  }
63 
64  friend bool operator<(future_status lhs, enum_type rhs) { return enum_type(lhs.value) < rhs; }
65 
66  friend bool operator<(enum_type lhs, future_status rhs) { return lhs < enum_type(rhs.value); }
67 
68  friend bool operator<=(future_status lhs, future_status rhs) {
69  return enum_type(lhs.value) <= enum_type(rhs.value);
70  }
71 
72  friend bool operator<=(future_status lhs, enum_type rhs) { return enum_type(lhs.value) <= rhs; }
73 
74  friend bool operator<=(enum_type lhs, future_status rhs) { return lhs <= enum_type(rhs.value); }
75 
76  friend bool operator>(future_status lhs, future_status rhs) {
77  return enum_type(lhs.value) > enum_type(rhs.value);
78  }
79 
80  friend bool operator>(future_status lhs, enum_type rhs) { return enum_type(lhs.value) > rhs; }
81 
82  friend bool operator>(enum_type lhs, future_status rhs) { return lhs > enum_type(rhs.value); }
83 
84  friend bool operator>=(future_status lhs, future_status rhs) {
85  return enum_type(lhs.value) >= enum_type(rhs.value);
86  }
87 
88  friend bool operator>=(future_status lhs, enum_type rhs) { return enum_type(lhs.value) >= rhs; }
89 
90  friend bool operator>=(enum_type lhs, future_status rhs) { return lhs >= enum_type(rhs.value); }
91 
92  private:
93  int value;
94  };
95 
96  namespace exception {
97  class HAZELCAST_API FutureUninitialized : public IException {
98  public:
99  FutureUninitialized(const std::string &source, const std::string &message) : IException(source,
100  message) { }
101  };
102  }
103 
111  template<typename V>
112  class Future {
113  public:
114  typedef std::auto_ptr<serialization::pimpl::Data> (*Decoder)(protocol::ClientMessage &response);
115 
119  Future(connection::CallFuture &callFuture,
120  serialization::pimpl::SerializationService &serializationService,
121  Decoder decoder) : callFuture(new connection::CallFuture(callFuture)),
122  serializationService(serializationService), decoderFunction(decoder) {
123  }
124 
130  Future(const Future &movedFuture) : callFuture(movedFuture.callFuture),
131  serializationService(movedFuture.serializationService),
132  decoderFunction(movedFuture.decoderFunction) {
133  }
134 
141  Future &operator=(const Future &movedFuture) {
142  this->callFuture = movedFuture.callFuture;
143  this->decoderFunction = movedFuture.decoderFunction;
144  return *this;
145  }
146 
147  virtual ~Future() {
148  }
149 
166  std::auto_ptr<V> get() {
167  if (!callFuture.get()) {
168  throw exception::FutureUninitialized("Future::get", "Future needs to be initialized. "
169  "It may have been moved from.");
170  }
171 
172  std::auto_ptr<protocol::ClientMessage> responseMsg = callFuture->get();
173 
174  assert(responseMsg.get());
175 
176  callFuture.reset();
177 
178  std::auto_ptr<serialization::pimpl::Data> response = decoderFunction(*responseMsg);
179 
180  std::auto_ptr<V> result = serializationService.toObject<V>(response.get());
181 
182  return result;
183  }
184 
196  future_status wait_for(int64_t timeoutInMilliseconds) const {
197  if (!callFuture.get()) {
198  throw exception::FutureUninitialized("Future::get", "Future needs to be initialized.");
199  }
200 
201  return callFuture->waitFor(timeoutInMilliseconds) ? future_status::ready : future_status::timeout;
202  }
203 
210  void wait() const {
211  wait_for(INT64_MAX);
212  }
213 
221  bool valid() const {
222  return callFuture.get() != NULL;
223  }
224 
225  private:
226  mutable std::auto_ptr<connection::CallFuture> callFuture;
227  serialization::pimpl::SerializationService &serializationService;
228  Decoder decoderFunction;
229  };
230 
234  template<>
235  class Future<TypedData> {
236  public:
237  typedef std::auto_ptr<serialization::pimpl::Data> (*Decoder)(protocol::ClientMessage &response);
238 
242  Future(connection::CallFuture &callFuture,
243  serialization::pimpl::SerializationService &serializationService,
244  Decoder decoder) : callFuture(new connection::CallFuture(callFuture)),
245  serializationService(serializationService), decoderFunction(decoder) {
246  }
247 
253  Future(const Future &movedFuture) : callFuture(movedFuture.callFuture),
254  serializationService(movedFuture.serializationService),
255  decoderFunction(movedFuture.decoderFunction) {
256  }
257 
264  Future &operator=(const Future &movedFuture) {
265  this->callFuture = movedFuture.callFuture;
266  this->decoderFunction = movedFuture.decoderFunction;
267  return *this;
268  }
269 
270  virtual ~Future() {
271  }
272 
289  TypedData get() {
290  if (!callFuture.get()) {
291  throw exception::FutureUninitialized("Future::get", "Future needs to be initialized. "
292  "It may have been moved from.");
293  }
294 
295  std::auto_ptr<protocol::ClientMessage> responseMsg = callFuture->get();
296 
297  assert(responseMsg.get());
298 
299  callFuture.reset();
300 
301  std::auto_ptr<serialization::pimpl::Data> response = decoderFunction(*responseMsg);
302 
303  return TypedData(response, serializationService);
304  }
305 
317  future_status wait_for(int64_t timeoutInMilliseconds) const {
318  if (!callFuture.get()) {
319  throw exception::FutureUninitialized("Future::get", "Future needs to be initialized.");
320  }
321 
322  return callFuture->waitFor(timeoutInMilliseconds) ? future_status::ready : future_status::timeout;
323  }
324 
331  void wait() const {
332  wait_for(INT64_MAX);
333  }
334 
342  bool valid() const {
343  return callFuture.get() != NULL;
344  }
345 
346  private:
347  mutable std::auto_ptr<connection::CallFuture> callFuture;
348  serialization::pimpl::SerializationService &serializationService;
349  Decoder decoderFunction;
350  };
351  }
352 }
353 
354 #if defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64)
355 #pragma warning(pop)
356 #endif
357 
358 #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:242
Future(const Future &movedFuture)
This is actually a move constructor Constructs a Future with the shared state of movedFuture using mo...
Definition: Future.h:253
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:317
Future & operator=(const Future &movedFuture)
Assigns the contents of another future object.
Definition: Future.h:264
void wait() const
Blocks until the result becomes available.
Definition: Future.h:331
Definition: Future.h:35
bool valid() const
Checks if the future refers to a shared state.
Definition: Future.h:342
This is a unique Future.
Definition: Future.h:112
bool valid() const
Checks if the future refers to a shared state.
Definition: Future.h:221
Future(connection::CallFuture &callFuture, serialization::pimpl::SerializationService &serializationService, Decoder decoder)
This constructor is only for internal use!!!!
Definition: Future.h:119
void wait() const
Blocks until the result becomes available.
Definition: Future.h:210
future_status wait_for(int64_t timeoutInMilliseconds) const
Waits for the result to become available.
Definition: Future.h:196
Definition: MapEntryView.h:32
Future & operator=(const Future &movedFuture)
Assigns the contents of another future object.
Definition: Future.h:141
Future(const Future &movedFuture)
This is actually a move constructor Constructs a Future with the shared state of movedFuture using mo...
Definition: Future.h:130
TypedData class is a wrapper class for the serialized binary data.
Definition: TypedData.h:40