-
Notifications
You must be signed in to change notification settings - Fork 463
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improve Get-Jobs performance with large numbers of jobs #2913
Comments
CUPS.org User: mike How many jobs? Even 500 jobs shouldn't take very long to load... |
CUPS.org User: twaugh.redhat Tens of thousands. Even 5,000 jobs takes over 10s for 'lpstat -Wall -o', and that's without PreserveJobFiles being set. If PreserveJobFiles is set, it seems that cupsd wants to auto-type every job file as well... |
CUPS.org User: mike OK, I'm pushing this to a RFE for a future release (not 1.4), since the default limit is 500 jobs. It still shouldn't take that long to load the job history, but we'll just need to do some performance tuning for that use case. |
CUPS.org User: rojon Where comes the limit from? When looking in the current code, i can find only a hard limit in scheduler/ipp.c:6138 limit = 1000000; (cups-1.3.8-r7864) which is set if no limit is set by the requestor. Neither in the cgi-bin's nor in the lpstat, there is a limit imposed other than in ipp.c (yet). Even worser, even if a destination is given, the job-uri is not adapted to limit search only for destination, forcing to build an array of all jobs matching the "which-jobs" tag, before emiting an output. This results in a heavy degradation of the cupsd service. Also this consumes an incredible high amount of memory if you have to create an array of all "MaxJobFiles" elements, even searching for 10 matching entries, or for a specific printer ... |
CUPS.org User: mike The maximum size of the job history is controlled by the MaxJobs directive in cupsd.conf. The default value for this is 500. |
CUPS.org User: rojon This limits the number of max reported Jobs efectivly, nonetheless, this does not impose a limit to IPP_GET_JOBS if you want to store lets say about 50000 Jobs for a Job-History. I think we could change at least lpstat to behave more effective and give cups the chance to serve jobs, even if we retrieve a full list of completed jobs. Find attached a patch to lpstat.c to behave much friendlier ... |
CUPS.org User: twaugh.redhat Attached is a patch to do the same for the web interface. |
CUPS.org User: mike Considering for CUPS 1.5, although I may rev the cupsGetJobs API to handle this for all of the current clients. |
CUPS.org User: mike Pushing to future release; we can't use the patches as-is and I'd like to do some different optimizations when the client is asking for already-cached data. |
CUPS.org User: twaugh.redhat Any update on this? This is essentially a denial of service using what should be a non-privileged operation. |
CUPS.org User: mike The work is queued up for 1.6 and will likely be addressed in the coming weeks. |
CUPS.org User: mike Pushing out a bit; I want to add support for the new first-index attribute, and then we'll apply this. Too late for 1.6... |
CUPS.org User: twaugh.redhat I'm not sure how first-index will help this. If the client doesn't supply that attribute, Get-Jobs will have the same performance problems as it ever has. Perhaps the timer support (from the Avahi work I did) could be used to break up long operations into fairer portions? |
CUPS.org User: mike Tim, the first-index attribute fixes issues with using first-job-id in the "window fetching" changes you have provided (due to priority and state, job-id's may not come across in numerical order...) I am thinking about adding a default limit value of 500 (configurable of course) so that clients that just ask for job history will not cause the attributes of all jobs to be loaded; this combined with the latest changes to support time-based history preservation (STR #3143) should mitigate this issue until cupsd can better deal with long history reports. Future versions of cupsd will be multi-threaded as well, so a single long-running operation won't impact other clients like it does today. |
CUPS.org User: mike Fixed in Subversion repository. The attached patch adds a small amount of additional caching to allow the most common uses of Get-Jobs to work without requiring the full job history to be reloaded. When loading is necessary, we also now limit the number of returned jobs to 500 (and return this limit in the "limit" attribute in the response). I'm not incorporating the web interface or command changes since they only ask for already-cached data and won't need any special handling. But if someone does extend the web template to show more job attributes we will limit the list to the 500 most recently completed jobs for a given printer (or for all queues for the server-wide job listings). |
"str-2913-lpstat-1.patch": --- systemv/lpstat.c Sat Jul 12 00:48:49 2008
DEBUG_printf(("show_jobs(%p, %p, %p)\n", http, dests, users));
/*
for (attr = response->attrs; attr != NULL; attr = attr->next) }
return (0); |
"str-2913-lpstat-2.patch": --- systemv/lpstat.c Sat Jul 12 00:48:49 2008
DEBUG_printf(("show_jobs(%p, %p, %p)\n", http, dests, users));
/*
for (attr = response->attrs; attr != NULL; attr = attr->next) }
return (0); |
"cups-showjobs.patch": diff --git a/cgi-bin/ipp-var.c b/cgi-bin/ipp-var.c
/*
if ((var = cgiGetVariable("FIRST")) != NULL)
- cgiSetVariable("TOTAL", url);
- }
|
"str2913.patch": Index: scheduler/ipp.c--- scheduler/ipp.c (revision 12066) if ((attr = ippFindAttribute(con->request, "job-name", IPP_TAG_ZERO)) == NULL)
if ((attr = ippFindAttribute(job->attrs, "job-originating-host-name",
kbytes = (cupsFileTell(out) + 1023) / 1024;
cupsFileClose(out);
@@ -6101,9 +6151,13 @@
/*
ra = create_requested_array(con->request);
/*
cupsdUpdateQuota(printer, job->username, 0, kbytes);
/* cupsdUpdateQuota(printer, job->username, 0, kbytes);
snprintf(filename, sizeof(filename), "%s/d%05d-%03d", RequestRoot, job->id, Index: scheduler/job.c--- scheduler/job.c (revision 12066)
@@ -1826,6 +1827,12 @@
/*
if (!job->num_files)
|
CUPS.org User: twaugh.redhat Thanks. This looks like a good solution. |
Version: 2.0-feature
CUPS.org User: twaugh.redhat
If there are very many completed jobs preserved in the history, an IPP-Get-Jobs operation may tie up the scheduler in get_jobs() for several minutes with 100% CPU usage, preventing jobs being serviced.
Perhaps it ought to be possible to configure CUPS to deny requests that do not use the 'limit' attribute if the result would exceed some certain number of jobs?
The text was updated successfully, but these errors were encountered: