static void update_subscription_ticks(struct watchman_client_subscription *sub, w_query_res *res) { // create a new spec that will be used the next time if (sub->query->since_spec) { w_clockspec_free(sub->query->since_spec); } sub->query->since_spec = w_clockspec_new_clock(res->root_number, res->ticks); }
void w_assess_trigger(w_root_t *root, struct watchman_trigger_command *cmd) { w_query_res res; struct w_clockspec *since_spec = cmd->query->since_spec; if (since_spec && since_spec->tag == w_cs_clock) { w_log(W_LOG_DBG, "running trigger rules! since %" PRIu32 "\n", since_spec->clock.ticks); } else { w_log(W_LOG_DBG, "running trigger rules!\n"); } // Triggers never need to sync explicitly; we are only dispatched // at settle points which are by definition sync'd to the present time cmd->query->sync_timeout = 0; if (!w_query_execute(cmd->query, root, &res, trigger_generator, cmd)) { w_log(W_LOG_ERR, "error running trigger query: %s", res.errmsg); w_query_result_free(&res); return; } w_log(W_LOG_DBG, "trigger generated %" PRIu32 " results\n", res.num_results); // create a new spec that will be used the next time cmd->query->since_spec = w_clockspec_new_clock(res.root_number, res.ticks); if (res.num_results) { spawn_command(root, cmd, &res, since_spec); } if (since_spec) { w_clockspec_free(since_spec); since_spec = NULL; } w_query_result_free(&res); }
static json_t *build_subscription_results( struct watchman_client_subscription *sub, w_root_t *root) { w_query_res res; json_t *response; json_t *file_list; char clockbuf[128]; struct w_clockspec *since_spec = sub->query->since_spec; if (since_spec && since_spec->tag == w_cs_clock) { w_log(W_LOG_DBG, "running subscription rules! since %" PRIu32 "\n", since_spec->clock.ticks); } else { w_log(W_LOG_DBG, "running subscription rules!\n"); } // Subscriptions never need to sync explicitly; we are only dispatched // at settle points which are by definition sync'd to the present time sub->query->sync_timeout = 0; if (!w_query_execute(sub->query, root, &res, subscription_generator, sub)) { w_log(W_LOG_ERR, "error running subscription query: %s", res.errmsg); w_query_result_free(&res); return NULL; } w_log(W_LOG_DBG, "subscription generated %" PRIu32 " results\n", res.num_results); if (res.num_results == 0) { w_query_result_free(&res); return NULL; } file_list = w_query_results_to_json(&sub->field_list, res.num_results, res.results); w_query_result_free(&res); response = make_response(); // It is way too much of a hassle to try to recreate the clock value if it's // not a relative clock spec, and it's only going to happen on the first run // anyway, so just skip doing that entirely. if (since_spec && since_spec->tag == w_cs_clock && clock_id_string(since_spec->clock.root_number, since_spec->clock.ticks, clockbuf, sizeof(clockbuf))) { set_prop(response, "since", json_string_nocheck(clockbuf)); } if (clock_id_string(res.root_number, res.ticks, clockbuf, sizeof(clockbuf))) { set_prop(response, "clock", json_string_nocheck(clockbuf)); } // create a new spec that will be used the next time if (since_spec) { w_clockspec_free(since_spec); since_spec = NULL; } sub->query->since_spec = w_clockspec_new_clock(res.root_number, res.ticks); set_prop(response, "is_fresh_instance", json_boolean(res.is_fresh_instance)); set_prop(response, "files", file_list); set_prop(response, "root", json_string(root->root_path->buf)); set_prop(response, "subscription", json_string(sub->name->buf)); return response; }