Kinetic C/C++ Client
 All Classes Functions Variables Pages
DoxygenMainPage.md
1 Quickstart {#mainpage}
2 ======================
3 This library allows building C++ programs that interact with a Kinetic API implementation. It provides blocking and non-blocking styles of interaction depending on application needs.
4 
5 Including the library
6 ---------------------
7 The library can be built as a static or shared library. For examples of how to include the library in a CMake-based project see the examples repo at [https://github.com/Seagate/kinetic-cpp-examples](https://github.com/Seagate/kinetic-cpp-examples). Applications also need to add the `include/kinetic` directory to the include path and include `kinetic/kinetic.h`.
8 
9 Opening a connection
10 --------------------
11 Before creating a connection, first create a `KineticConnectionFactory` using the handy helper method:
12 
13  kinetic::KineticConnectionFactory kinetic_connection_factory = kinetic::NewKineticConnectionFactory();
14 
15 A single `KineticConnectionFactory` can be used to create many connections. Deleting the connection factory won't affect existing connections.
16 
17 Next, create a connection options object to indicate the IP, port, user identity, and so on:
18 
19  kinetic::ConnectionOptions options;
20  options.host = my_host;
21  options.port = my_port;
22  options.user_id = my_user_id;
23  options.hmac_key = my_hmac_key;
24 
25 Finally, open the connection:
26 
27  std::unique_ptr<kinetic::NonblockingKineticConnection> connection;
28  kinetic::KineticStatus status = kinetic_connection_factory.NewNonblockingConnection(options, timeout_in_seconds, connection);
29 
30 *Note*: If the connection needs to be shared between threads, call `NewThreadsafeNonblockingConnection` instead.
31 
32 To check whether the connection succeeded, check the value of `status.ok()`. If it's false, additional error information is available by calling `status.statusCode()` and `status.message()`.
33 
34 The factory can create threadasafe and non-threadsafe variants of blocking and nonblocking clients. Blocking clients can also be created from an existing nonblocking client using the `BlockingKineticClient` constructor which takes a `NonblockingKineticConnection`.
35 The benefit of this approach is that both clients will use the same underyling connection. This is not necessarily threadsafe. If you use a nonblocking and blocking client which use the same underlying connection, then there are no guarantees about which thread is will process callbacks.
36 
37 Performing blocking GET/PUT operations
38 --------------------------------------
39 PUT and GET calls make use of the `kientic::KineticRecord` class, which bundles the value/version/tag/algorithm fourpule allows construction via a series of `shared_ptr` instances (avoiding a copy) or a series of `string`s (avoiding extra typing).
40 
41 To PUT a key:
42 
43  blocking_connection->Put(
44  key,
45  version,
46  kinetic::IGNORE_VERSION,
47  KineticRecord(value, version, tag, Message_Algorithm_SHA1));
48 
49 Like most operations in the Kinetic C++ client, `Put` returns a `KineticStatus` object that indicates success and provides error information.
50 
51 *Note*: The Kinetic C++ client makes extensive use of `shared_ptr` and `unique_ptr` to make memory transfer and ownership explicit while avoiding unnecessary copies. However, applications that prefer to avoid the complexity of `shared_ptr` and `unique_ptr` can just pass in `std::string` instances and accept the additional overhead.
52 
53 GETting a key works similarly:
54 
55  std::unique_ptr<KineticRecord> record;
56  blocking_connection->Get(key, record);
57 
58 Performing non-blocking GET/PUT operations
59 ------------------------------------------
60 The blocking API is convenient for simplicity or thread-per-connection style designs, but many applications use a non-blocking event-driven design. For these applications, it makes more sense to use a non-blocking API. The Kinetic C++ client's non-blocking API is very similar to the blocking API, with two important differences. First, all methods take an additional callback parameter that will be called once the operation succeeds or fails. Secondly, to actually perform IO the `Run` method needs to be called repeatedly.
61 
62 As a simple example to perform several writes, first create a callback
63 class to receive success and failure messages:
64 
65  // PutCallback definition:
66  class PutCallback : public PutCallbackInterface {
67  public:
68  void Success() {
69  printf("Success!\n");
70  }
71  void Failure(KineticStatus error) {
72  printf("Dismal failure!\n");
73  }
74  };
75  //
76  // ...
77  //
78  // PutCallback instantiation
79  auto callback = make_shared<PutCallback>();
80 
81 Then enqueue a series of operations:
82 
83  auto record = make_shared<KineticRecord>(value, version, tag, Message_Algorithm_SHA1);
84  nonblocking_connection->Put(key1, version, kinetic::IGNORE_VERSION, record, callback);
85  Message_Algorithm_SHA1);
86  nonblocking_connection->Put(key2, version, kinetic::IGNORE_VERSION, record, callback);
87  Message_Algorithm_SHA1);
88  nonblocking_connection->Put(key3, version, kinetic::IGNORE_VERSION, record, callback);
89 
90 Finally, call `Run` repeatedly to actually execute the operations:
91 
92  fd_set read_fds, write_fds;
93  int nfd = 0;
94  nonblocking_connection->Run(&read_fds, &write_fds, &nfd);
95  while (there_is_work_to_do) {
96  while (select(nfd + 1, &read_fds, &write_fds, NULL, NULL) <= 0);
97  nonblocking_connection->.Run(&read_fds, &write_fds, &num_fds);
98  }
99 
100 If desired, other fds can be added to the `fd_set`s so that the `select` call can wait for IO to be ready on fds controlled by the Kinetic API or other parts of the application.
101 
102 GETs work very similarly. First, a callback implementation:
103 
104  class GetCallback : public GetCallbackInterface {
105  public:
106  void Success(const std::string &key, std::unique_ptr<KineticRecord> record) {
107  printf("Good\n");
108  }
109  void Failure(KineticStatus error) {
110  printf("Bad\n");
111  }
112  };
113  //
114  // ...
115  //
116  // GetCallback instantiation
117  auto callback = make_shared<GetCallback>();
118 
119 Next, enqueue some operations:
120 
121  nonblocking_connection->Get(key_1, callback);
122  nonblocking_connection->Get(key_2, callback);
123  nonblocking_connection->Get(key_3, callback);
124 
125 The `Run` loop works exactly the same way as it does for the PUT case. Multiple GET/PUT/management operations can all be enqueued and they will be executed one at a time in order by repeated `Run` calls.