<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN" "http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">

<chapter id="backend-spawn">
  <title>Spawned Backends</title>
  <sect1 id="backends-spawn-intro">
    <title>Introduction</title>
    <para>
      If you do not have a C or C++ language binding, PackageKit executes
      helper scripts written in pretty much any language.
      It then watches the standard out and standard error and parses the
      output into compiled backend commands.
      This means a python library can be interfaced easily with a C backend.
    </para>
    <para>
      Even when using helpers, a compiled backend stub is still used for
      two reasons:
    </para>
    <itemizedlist>
      <listitem>
        <para>
          It is still needed for the dlopen internally in PackageKit.
        </para>
      </listitem>
      <listitem>
        <para>
          You can add cleverness in the C backend that you might not want to
          do in the scripted backend, for example using a hash table in C
          rather than checking all the names in awk.
        </para>
      </listitem>
    </itemizedlist>
    <para>
      Backends are typically open-programmable, which means we can define a
      standard for what goes on stdin and stdout to try and maximise
      the common code between the backends.
    </para>
    <para>
      If you are unable to write scripts that conform to these specifications
      then just launch a PkSpawn object in the compiled helper with stdout
      callbacks and then try to do screenscraping in the backend.
    </para>
    <para>
      Backends scripts are run with arguments and data is sent to standard out
      and standard error asynchronously so that PackageKit can proxy this to D-Bus.
      A method has command line arguments separated with tabs, and data is also
      separated with tabs.
    </para>
    <para>
      It is important to flush the standard output after each output, else
      Linux will helpfully buffer the output into more efficient size chunks.
      If you do not flush, then there will be a long IPC delay.
      Flushing can be achieved in C using <literal>fflush</literal> or in python
      using <literal>sys.stdout.flush()</literal>.
    </para>
    <para>
      The "dispatcher" mode is where a command is used to startup the
      backend, for instance <literal>yumBackend.py search-name none power</literal>
      and then the backend then sits and waits for more standard input.
      Further operations can be done on the loaded backend sending commands
      to stdin, e.g. <literal>search-name none power</literal>.
      If there are no more operations after a preset time (default 5 seconds)
      then the backend is sent <literal>exit</literal> over stdin, and the
      backend terminates.
      The daemon will ensure the operations are serialised, and that backends
      not sending <literal>finished</literal> are cleaned up properly.
    </para>
    <para>
      The dispatcher mode does not have to implemented in python; any
      language that can read from stdin can block and be used in this way.
    </para>
</sect1>

</chapter>
