if (orig_state == LTTNG_LIVE_STREAM_QUIESCENT_NO_DATA && last_inact_ts == curr_inact_ts) {
/*
- * Because the stream is in the QUIESCENT_NO_DATA
- * state, we can assert that the last_inactivity_ts was
- * set and can be safely used in the `if` above.
- */
+ * Because the stream is in the QUIESCENT_NO_DATA
+ * state, we can assert that the last_inactivity_ts was
+ * set and can be safely used in the `if` above.
+ */
BT_ASSERT(lttng_live_stream->last_inactivity_ts.is_set);
ret = LTTNG_LIVE_ITERATOR_STATUS_AGAIN;
}
}
- BT_COMP_LOGD("Updating all streams and metadata for session: "
+ BT_COMP_LOGD("Updating all data streams: "
"session-id=%" PRIu64 ", session-name=\"%s\"",
session->id, session->session_name->str);
status = lttng_live_session_get_new_streams(session, lttng_live_msg_iter->self_msg_iter);
- if (status != LTTNG_LIVE_ITERATOR_STATUS_OK && status != LTTNG_LIVE_ITERATOR_STATUS_END) {
+ switch (status) {
+ case LTTNG_LIVE_ITERATOR_STATUS_OK:
+ break;
+ case LTTNG_LIVE_ITERATOR_STATUS_END:
+ /*
+ * We received a `_END` from the `_get_new_streams()` function,
+ * which means no more data will ever be received from the data
+ * streams of this session. But it's possible that the metadata
+ * is incomplete.
+ * The live protocol guarantees that we receive all the
+ * metadata needed before we receive data streams needing it.
+ * But it's possible to receive metadata NOT needed by
+ * data streams after the session was closed. For example, this
+ * could happen if a new event is registered and the session is
+ * stopped before any tracepoint for that event is actually
+ * fired.
+ */
+ BT_COMP_LOGD(
+ "Updating streams returned _END status. Override status to _OK in order fetch any remaining metadata:"
+ "session-id=%" PRIu64 ", session-name=\"%s\"",
+ session->id, session->session_name->str);
+ status = LTTNG_LIVE_ITERATOR_STATUS_OK;
+ break;
+ default:
goto end;
}
+ BT_COMP_LOGD("Updating metadata stream for session: "
+ "session-id=%" PRIu64 ", session-name=\"%s\"",
+ session->id, session->session_name->str);
+
trace_idx = 0;
while (trace_idx < session->traces->len) {
struct lttng_live_trace *trace =
status = lttng_live_get_session(lttng_live_msg_iter, session);
switch (status) {
case LTTNG_LIVE_ITERATOR_STATUS_OK:
- break;
case LTTNG_LIVE_ITERATOR_STATUS_END:
- status = LTTNG_LIVE_ITERATOR_STATUS_OK;
+ /*
+ * A session returned `_END`. Other sessions may still
+ * be active so we override the status and continue
+ * looping if needed.
+ */
break;
default:
goto end;
lttng_live_msg_iter = lttng_live_msg_iter_create(lttng_live, self_msg_it);
if (!lttng_live_msg_iter) {
- status = BT_MESSAGE_ITERATOR_CLASS_INITIALIZE_METHOD_STATUS_MEMORY_ERROR;
BT_COMP_LOGE_APPEND_CAUSE(self_comp, "Failed to create lttng_live_msg_iter");
+ status = BT_MESSAGE_ITERATOR_CLASS_INITIALIZE_METHOD_STATUS_MEMORY_ERROR;
goto error;
}
*/
BT_COMP_LOGE_APPEND_CAUSE(self_comp, "Interrupted while creating viewer connection");
}
+
+ status = BT_MESSAGE_ITERATOR_CLASS_INITIALIZE_METHOD_STATUS_ERROR;
goto error;
}
*/
BT_COMP_LOGE_APPEND_CAUSE(self_comp, "Interrupted when creating viewer session");
}
+
+ status = BT_MESSAGE_ITERATOR_CLASS_INITIALIZE_METHOD_STATUS_ERROR;
goto error;
}
"component parameter: url =\"%s\"",
SESS_NOT_FOUND_ACTION_PARAM, SESS_NOT_FOUND_ACTION_FAIL_STR,
lttng_live->params.url->str);
+ status = BT_MESSAGE_ITERATOR_CLASS_INITIALIZE_METHOD_STATUS_ERROR;
goto error;
case SESSION_NOT_FOUND_ACTION_END:
BT_COMP_LOGI(
goto end;
error:
- status = BT_MESSAGE_ITERATOR_CLASS_INITIALIZE_METHOD_STATUS_ERROR;
lttng_live_msg_iter_destroy(lttng_live_msg_iter);
end:
return status;
}
static struct bt_param_validation_map_value_entry_descr list_sessions_params[] = {
- {URL_PARAM,
- BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_MANDATORY,
- {bt_param_validation_value_descr::string_t}},
+ {URL_PARAM, BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_MANDATORY,
+ bt_param_validation_value_descr::makeString()},
BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_END};
static bt_component_class_query_method_status
return action;
}
-static bt_param_validation_value_descr inputs_elem_descr {
- bt_param_validation_value_descr::string_t,
-};
+static bt_param_validation_value_descr inputs_elem_descr =
+ bt_param_validation_value_descr::makeString();
static const char *sess_not_found_action_choices[] = {
SESS_NOT_FOUND_ACTION_CONTINUE_STR,
};
static struct bt_param_validation_map_value_entry_descr params_descr[] = {
- {INPUTS_PARAM,
- BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_MANDATORY,
- {bt_param_validation_value_descr::array_t, 1, 1, inputs_elem_descr}},
- {SESS_NOT_FOUND_ACTION_PARAM,
- BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_OPTIONAL,
- {bt_param_validation_value_descr::string_t, sess_not_found_action_choices}},
+ {INPUTS_PARAM, BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_MANDATORY,
+ bt_param_validation_value_descr::makeArray(1, 1, inputs_elem_descr)},
+ {SESS_NOT_FOUND_ACTION_PARAM, BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_OPTIONAL,
+ bt_param_validation_value_descr::makeString(sess_not_found_action_choices)},
BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_END};
static bt_component_class_initialize_method_status