diff --git a/bin/gearadmin.cc b/bin/gearadmin.cc index d51956573..de2fb150b 100644 --- a/bin/gearadmin.cc +++ b/bin/gearadmin.cc @@ -139,7 +139,7 @@ int main(int args, char *argv[]) ("create-function", boost::program_options::value(), "Create the function from the server.") ("cancel-job", boost::program_options::value(), "Remove a given job from the server's queue") ("drop-function", boost::program_options::value(), "Drop the function from the server.") - ("show-unique-jobs", "Show unique IDs of jobs on the server.") + ("show-unique-jobs", "Show job handles and unique IDs of jobs on the server.") ("show-jobs", "Show all jobs on the server.") ("getpid", "Get Process ID for the server.") ("status", "Status for the server.") diff --git a/docs/source/bin/gearadmin.rst b/docs/source/bin/gearadmin.rst index e1e17dea3..ff9c9f5e3 100644 --- a/docs/source/bin/gearadmin.rst +++ b/docs/source/bin/gearadmin.rst @@ -52,7 +52,7 @@ SYNOPSIS .. option:: --show-unique-jobs - Show unique IDs of jobs on the server. + Show the job handle and unique ID of each job on the server. .. option:: --show-jobs diff --git a/docs/source/protocol/text.rst b/docs/source/protocol/text.rst index 38f6b6b91..184306155 100644 --- a/docs/source/protocol/text.rst +++ b/docs/source/protocol/text.rst @@ -24,7 +24,9 @@ The following list represents the current list of commands supported. You can is .. describe:: show unique jobs - List all of the unique job ids that the server currently is processesing or waiting to process. + List all of the jobs that the server currently is processing or waiting + to process, one per line, as the job handle followed by a tab and the + unique job id. The handle can be passed to ``cancel job``. .. describe:: create diff --git a/libgearman-server/text.cc b/libgearman-server/text.cc index abc10a7b2..7977773c5 100644 --- a/libgearman-server/text.cc +++ b/libgearman-server/text.cc @@ -204,7 +204,8 @@ gearmand_error_t server_run_text(gearman_server_con_st *server_con, server_job != NULL; server_job= server_job->unique_next) { - data.vec_append_printf("%.*s\n", int(server_job->unique_length), server_job->unique); + data.vec_append_printf("%s\t%.*s\n", server_job->job_handle, + int(server_job->unique_length), server_job->unique); } } diff --git a/tests/cli.cc b/tests/cli.cc index bee37ffbf..7a7a11cb4 100644 --- a/tests/cli.cc +++ b/tests/cli.cc @@ -285,6 +285,72 @@ static test_return_t gearadmin_show_unique_jobs_TEST(void* object) return TEST_SUCCESS; } +// issue #81: each line of --show-unique-jobs is "\t", so +// the handle can be passed to --cancel-job. +static test_return_t gearadmin_show_unique_jobs_handle_TEST(void* object) +{ + cli::Context *context= (cli::Context*)object; + + // No worker is registered for this function, so the job stays queued. + gearman_job_handle_t job_handle; + { + libgearman::Client client(context->port()); + ASSERT_EQ(GEARMAN_SUCCESS, + gearman_client_do_background(&client, + __func__, // function + __func__, // unique + NULL, 0, // workload + job_handle)); + } + + std::string expected(job_handle); + expected+= "\t"; + expected+= __func__; + expected+= "\n"; + + char port_arg[1024]; + snprintf(port_arg, sizeof(port_arg), "--port=%d", int(context->port())); + + { + Application app("bin/gearadmin", true); + app.add_option(port_arg); + app.add_option("--show-unique-jobs"); + ASSERT_EQ(Application::SUCCESS, app.run()); + ASSERT_EQ(Application::SUCCESS, app.join()); + + libtest::vchar_t stdout_result= app.stdout_result(); + std::string output(stdout_result.begin(), stdout_result.end()); + ASSERT_TRUE_(output.find(expected) != std::string::npos, + "expected `%s' in `%s'", expected.c_str(), output.c_str()); + } + + std::string cancel_arg("--cancel-job="); + cancel_arg+= job_handle; + const char *cancel_args[]= { port_arg, cancel_arg.c_str(), 0 }; + ASSERT_EQ(EXIT_SUCCESS, exec_cmdline("bin/gearadmin", cancel_args, true)); + + // Cancellation is lazy: the job is only marked as ignored (and freed once + // a worker would take it), which --show-jobs reports as + // "\t\t\t". + std::string cancelled(job_handle); + cancelled+= "\t0\t1\t0\n"; + + { + Application app("bin/gearadmin", true); + app.add_option(port_arg); + app.add_option("--show-jobs"); + ASSERT_EQ(Application::SUCCESS, app.run()); + ASSERT_EQ(Application::SUCCESS, app.join()); + + libtest::vchar_t stdout_result= app.stdout_result(); + std::string output(stdout_result.begin(), stdout_result.end()); + ASSERT_TRUE_(output.find(cancelled) != std::string::npos, + "expected `%s' in `%s'", cancelled.c_str(), output.c_str()); + } + + return TEST_SUCCESS; +} + static test_return_t gearadmin_cancel_job_TEST(void* object) { cli::Context *context= (cli::Context*)object; @@ -441,6 +507,7 @@ test_st gearadmin_tests[] ={ {"--cancel-job", 0, gearadmin_cancel_job_TEST}, {"--show-jobs", 0, gearadmin_show_jobs_TEST}, {"--show-unique-jobs", 0, gearadmin_show_unique_jobs_TEST}, + {"gearman_client_do_background() --show-unique-jobs --cancel-job", 0, gearadmin_show_unique_jobs_handle_TEST}, {"--status", 0, gearadmin_status_TEST}, {"--priority-status", 0, gearadmin_priority_status_TEST}, {"gearman_client_do_background(100) --status", 0, gearadmin_status_with_jobs_TEST},