Cursors
커서 실패 처리
커서는 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)
테일 커서(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를 테일링하는 예시입니다.
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", >); BSON_APPEND_TIMESTAMP (>, "$gt", last_time, 0); bson_append_document_end (&query, >); 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({})
를 수행한 샘플 입니다.