[cups-devel] flexible datastore proposal

Trevor Woerner twoerner at gmail.com
Wed Jan 11 08:40:08 PST 2023


Hi CUPS community,

I work for a company that is interested in using CUPS for office printing. One
of the areas we would like to focus on is high uptime and high availability.

Looking through the CUPS code we're drawn to the "array" class which is used
to store several sets of information useful to the CUPS server. Being entirely
in-memory, should an instance of CUPS be down or unavailable for any reason,
uptime and availability would suffer.

One thought we had would be to move all those sets of information currently
being stored in the in-memory arrays to a set of database tables. Databases
can be replicated and otherwise be made highly distributed and available quite
easily. This way if a CUPS server goes down or is unavailable for whatever
reason, a new CUPS server could be spun up and simply continue on where the
other one left off. It's probably more complicated than that, but at the very
least getting that information out of each running process and into a
distributed location would be a start. 

We realize that the current in-memory arrays work perfectly fine for most
use-cases. We wouldn't want to force users to use a database. Therefore we're
not proposing to replace the array, but rather to add a layer of indirection
which, by default, would continue to use the array, but could be pointed at a
database should the user so choose.

By way of a concrete example, take the cupsArrayAdd() function:

1. My first step would be to go through the CUPS code base and replace each
   instance of cupsArrayAdd with, say, cupsDatastoreAdd (except in the array
   test files)

2. Then I would add an optional ./configure time option such as:
	   $ ./configure --with-datastore=Array

   Currently the only option would be Array, as a first step, but eventually
   other options could be "Database" or "ODBC". If --with-datastore is not
   specified, the default is "Array"

3. I create a cups/datastore.h file in which I use C preprocessor
   statements to:

	#define _DATASTORE_FN(ds,fn) cups##ds##fn
	#define DATASTORE_FN(ds,fn) _DATASTORE_FN(ds,fn)

	#define cupsDatastoreAdd DATASTORE_FN(CUPS_DEFAULT_DATASTORE,Add)

   which, in this case, simply redefines cupsDatastoreAdd back to
   cupsArrayAdd. As a result, this has no effect whatsoever on the existing
   array class or code in the default configuration. None of that code would
   need to be changed or littered with ugly #ifdefs etc

4. Going forward I then add more options to the --with-datastore ./configure
   option and write a corresponding set of cupsXXYY functions (where XX
   specifies the specific datastore and YY are the individual functions such
   as "Add" etc.)

Certain datastore options might also require additional ./configure options or
perhaps require a datastore-specific configuration file. For example:
	$ ./configure --with-datastore=ODBC --database=sqlite
This would also generate and use a conf/<datastore>.conf.in file and/or a
conf/<database>.conf.in file to allow the user to specify certificates,
authentication, server, port, and other database information.

If this (or some variation thereof) sounds interesting to you, we'd like to
work on the code changes then work with you to get it upstreamed to your
satisfaction.

Thoughts?

Best regards,
	Trevor


More information about the cups-devel mailing list