/** * afsql_dd_insert_db: * * This function is running in the database thread * * Returns: FALSE to indicate that the connection should be closed and * this destination suspended for time_reopen() time. **/ static gboolean afsql_dd_insert_db(AFSqlDestDriver *self) { GString *table, *query_string; LogMessage *msg; gboolean success; LogPathOptions path_options = LOG_PATH_OPTIONS_INIT; afsql_dd_connect(self); success = log_queue_pop_head(self->queue, &msg, &path_options, (self->flags & AFSQL_DDF_EXPLICIT_COMMITS), FALSE); if (!success) return TRUE; msg_set_context(msg); table = afsql_dd_validate_table(self, msg); if (!table) { /* If validate table is FALSE then close the connection and wait time_reopen time (next call) */ msg_error("Error checking table, disconnecting from database, trying again shortly", evt_tag_int("time_reopen", self->time_reopen), NULL); msg_set_context(NULL); g_string_free(table, TRUE); return afsql_dd_insert_fail_handler(self, msg, &path_options); } query_string = afsql_dd_construct_query(self, table, msg); if (self->flush_lines_queued == 0 && !afsql_dd_begin_txn(self)) return FALSE; success = afsql_dd_run_query(self, query_string->str, FALSE, NULL); if (success && self->flush_lines_queued != -1) { self->flush_lines_queued++; if (self->flush_lines && self->flush_lines_queued == self->flush_lines && !afsql_dd_commit_txn(self)) return FALSE; } g_string_free(table, TRUE); g_string_free(query_string, TRUE); msg_set_context(NULL); if (!success) return afsql_dd_insert_fail_handler(self, msg, &path_options); /* we only ACK if each INSERT is a separate transaction */ if ((self->flags & AFSQL_DDF_EXPLICIT_COMMITS) == 0) log_msg_ack(msg, &path_options); log_msg_unref(msg); step_sequence_number(&self->seq_num); self->failed_message_counter = 0; return TRUE; }
/** * afsql_dd_insert_db: * * This function is running in the database thread * * Returns: FALSE to indicate that the connection should be closed and * this destination suspended for time_reopen() time. **/ static gboolean afsql_dd_insert_db(AFSqlDestDriver *self) { GString *table, *query_string; LogMessage *msg; gboolean success; LogPathOptions path_options = LOG_PATH_OPTIONS_INIT; afsql_dd_connect(self); g_mutex_lock(self->db_thread_mutex); /* FIXME: this is a workaround because of the non-proper locking semantics * of the LogQueue. It might happen that the _queue() method sees 0 * elements in the queue, while the thread is still busy processing the * previous message. In that case arming the parallel push callback is * not needed and will cause assertions to fail. This is ugly and should * be fixed by properly defining the "blocking" semantics of the LogQueue * object w/o having to rely on user-code messing with parallel push * callbacks. */ log_queue_reset_parallel_push(self->queue); success = log_queue_pop_head(self->queue, &msg, &path_options, (self->flags & AFSQL_DDF_EXPLICIT_COMMITS), FALSE); g_mutex_unlock(self->db_thread_mutex); if (!success) return TRUE; msg_set_context(msg); table = afsql_dd_validate_table(self, msg); if (!table) { /* If validate table is FALSE then close the connection and wait time_reopen time (next call) */ msg_error("Error checking table, disconnecting from database, trying again shortly", evt_tag_int("time_reopen", self->time_reopen), NULL); msg_set_context(NULL); g_string_free(table, TRUE); return afsql_dd_insert_fail_handler(self, msg, &path_options); } query_string = afsql_dd_construct_query(self, table, msg); if (self->flush_lines_queued == 0 && !afsql_dd_begin_txn(self)) return FALSE; success = afsql_dd_run_query(self, query_string->str, FALSE, NULL); if (success && self->flush_lines_queued != -1) { self->flush_lines_queued++; if (self->flush_lines && self->flush_lines_queued == self->flush_lines && !afsql_dd_commit_txn(self, TRUE)) return FALSE; } g_string_free(table, TRUE); g_string_free(query_string, TRUE); msg_set_context(NULL); if (!success) return afsql_dd_insert_fail_handler(self, msg, &path_options); /* we only ACK if each INSERT is a separate transaction */ if ((self->flags & AFSQL_DDF_EXPLICIT_COMMITS) == 0) log_msg_ack(msg, &path_options); log_msg_unref(msg); step_sequence_number(&self->seq_num); self->failed_message_counter = 0; return TRUE; }