Docs Menu
Docs Home
/ / /
C 드라이버
/ /

Cursors

이 페이지의 내용

  • 커서 실패 처리
  • 서버 측 커서 삭제
  • 테일 커서(tailable cursor)

커서는 MongoDB 서버 에 존재합니다. 그러나 mongoc_cursor_t 구조는 로컬 프로세스 에 커서 에 대한 처리하다 을 제공합니다. 클라이언트 에서 커서 를 반복하는 동안 서버 에서 오류가 발생할 수 있습니다. 네트워크 파티션 이 발생할 수도 있습니다. 이는 애플리케이션이 커서 실패를 처리할 때 견고해야 함을 의미합니다.

커서를 반복하는 동안 오류가 발생했는지 확인해야 합니다. 오류를 강력하게 확인하는 방법은 다음 예시를 참조하세요.

static void
print_all_documents (mongoc_collection_t *collection)
{
mongoc_cursor_t *cursor;
const bson_t *doc;
bson_error_t error;
bson_t query = BSON_INITIALIZER;
char *str;
cursor = mongoc_collection_find_with_opts (collection, query, NULL, NULL);
while (mongoc_cursor_next (cursor, &doc)) {
str = bson_as_canonical_extended_json (doc, NULL);
printf ("%s\n", str);
bson_free (str);
}
if (mongoc_cursor_error (cursor, &error)) {
fprintf (stderr, "Failed to iterate all documents: %s\n", error.message);
}
mongoc_cursor_destroy (cursor);
}

MongoDB C 운전자 는 mongoc_cursor_destory 가 발생할 때 서버 측 커서 를 자동으로 파기합니다. 호출됩니다. 커서 작업을 완료한 후 이 함수를 호출하지 않으면 클라이언트 사이드에서 메모리 누수가 발생하고 서버 사이드에서 예비 메모리가 소모됩니다. 커서 가 시간 초과되지 않도록 구성된 경우 서버 에서 메모리 누수가 발생합니다.

테일 커서(tailable cursor)는 최종 결과를 반환한 후에도 열려 있는 커서입니다. This way, if more documents are added to a collection (i.e., to the cursor's result set), then you can continue to call mongoc_cursor_next to retrieve those additional results.

다음은 테일 커서(tailable cursor)의 사용을 보여주는 전체 테스트 사례입니다.

참고

테일 커서(tailable cursor)는 고정 사이즈 컬렉션에만 사용됩니다.

복제본 세트에서 oplog를 테일링하는 예시입니다.

mongoc-tail.c
#include <bson/bson.h>
#include <mongoc/mongoc.h>
#include <stdio.h>
#include <stdlib.h>
#ifdef _WIN32
#define sleep(_n) Sleep ((_n) * 1000)
#endif
static void
print_bson (const bson_t *b)
{
char *str;
str = bson_as_canonical_extended_json (b, NULL);
fprintf (stdout, "%s\n", str);
bson_free (str);
}
static mongoc_cursor_t *
query_collection (mongoc_collection_t *collection, uint32_t last_time)
{
mongoc_cursor_t *cursor;
bson_t query;
bson_t gt;
bson_t opts;
BSON_ASSERT (collection);
bson_init (&query);
BSON_APPEND_DOCUMENT_BEGIN (&query, "ts", &gt);
BSON_APPEND_TIMESTAMP (&gt, "$gt", last_time, 0);
bson_append_document_end (&query, &gt);
bson_init (&opts);
BSON_APPEND_BOOL (&opts, "tailable", true);
BSON_APPEND_BOOL (&opts, "awaitData", true);
cursor = mongoc_collection_find_with_opts (collection, &query, &opts, NULL);
bson_destroy (&query);
bson_destroy (&opts);
return cursor;
}
static void
tail_collection (mongoc_collection_t *collection)
{
mongoc_cursor_t *cursor;
uint32_t last_time;
const bson_t *doc;
bson_error_t error;
bson_iter_t iter;
BSON_ASSERT (collection);
last_time = (uint32_t) time (NULL);
while (true) {
cursor = query_collection (collection, last_time);
while (!mongoc_cursor_error (cursor, &error) && mongoc_cursor_more (cursor)) {
if (mongoc_cursor_next (cursor, &doc)) {
if (bson_iter_init_find (&iter, doc, "ts") && BSON_ITER_HOLDS_TIMESTAMP (&iter)) {
bson_iter_timestamp (&iter, &last_time, NULL);
}
print_bson (doc);
}
}
if (mongoc_cursor_error (cursor, &error)) {
if (error.domain == MONGOC_ERROR_SERVER) {
fprintf (stderr, "%s\n", error.message);
exit (1);
}
}
mongoc_cursor_destroy (cursor);
sleep (1);
}
}
int
main (int argc, char *argv[])
{
mongoc_collection_t *collection;
mongoc_client_t *client;
mongoc_uri_t *uri;
bson_error_t error;
if (argc != 2) {
fprintf (stderr, "usage: %s MONGO_URI\n", argv[0]);
return EXIT_FAILURE;
}
mongoc_init ();
uri = mongoc_uri_new_with_error (argv[1], &error);
if (!uri) {
fprintf (stderr,
"failed to parse URI: %s\n"
"error message: %s\n",
argv[1],
error.message);
return EXIT_FAILURE;
}
client = mongoc_client_new_from_uri (uri);
if (!client) {
return EXIT_FAILURE;
}
mongoc_client_set_error_api (client, 2);
collection = mongoc_client_get_collection (client, "local", "oplog.rs");
tail_collection (collection);
mongoc_collection_destroy (collection);
mongoc_uri_destroy (uri);
mongoc_client_destroy (client);
return EXIT_SUCCESS;
}

복제본 세트에 대해 이 예제를 컴파일하고 실행하여 업데이트가 적용되는지 확인하겠습니다.

$ gcc -Wall -o mongoc-tail mongoc-tail.c $(pkg-config --cflags --libs libmongoc-1.0)
$ ./mongoc-tail mongodb://example.com/?replicaSet=myReplSet
{
"h" : -8458503739429355503,
"ns" : "test.test",
"o" : {
"_id" : {
"$oid" : "5372ab0a25164be923d10d50"
}
},
"op" : "i",
"ts" : {
"$timestamp" : {
"i" : 1,
"t" : 1400023818
}
},
"v" : 2
}

출력 줄은 복제본 세트 의 mongo shell 에서 db.test.insert({}) 를 수행한 샘플 입니다.

다음도 참조하세요.

돌아가기

데이터 압축