## 17. Not Using Slonik - Bare Metal Slony-I Functions

There are cases where it may make sense to directly use the stored functions that implement the various pieces of Slony-I. Slonik doesn't do terribly much “magic;” it is common for Slonik commands to simply involve deciding on a node at which to apply a command, and then submit a SQL query consisting of a call to one of the Slony-I stored functions.

The developers of Slony-I anticipate that interested parties may wish to develop graphical tools as an alternative to Slonik; it would be entirely appropriate in such cases to submit configuration requests directly via the stored functions. If you plan to do so, it is suggested that you examine how the stored procedures get used in `slonik.c`, as that should be the most representative way of seeing correct use of the functions.

When debugging problems in “troubled” Slony-I clusters, it has also occasionally proven useful to use the stored functions. This has been particularly useful for cases where sl_listen configuration has been broken, and events have not been propagating properly. The “easiest” fix was to:

`select _slonycluster.droplisten(li_origin,li_provider,li_receiver) from _slonycluster.sl_listen;`

`select _slonycluster.storelisten(pa_server, pa_server, pa_client) from _slonycluster.sl_path;`

The result of this set of queries is to regenerate and propagate the listen paths. By running the main `_slonycluster.storelisten()` function, `STORE_LISTEN` events are raised to cause the listen paths to propagate to the other nodes in the cluster.

If there was a local problem on one node, and you didn't want the updates to propagate (this would be an unusual situation; you almost certainly want to fix things everywhere), the queries would instead be:

`select slonycluster.droplisten_int(li_origin,li_provider,li_receiver) from _slonycluster.sl_listen;`

`select _slonycluster.storelisten_int(pa_server, pa_server, pa_client) from _slonycluster.sl_path;`

If you are planning to add Slony-I support to other tools (e.g. - adding replication support to something like pgAdmin III ), you need to be clear on where various functions need to be called. The normal “protocol” is thus:

- The “main” function (e.g. - without the `_int` suffix) is called on a “relevant” node in the Slony-I cluster.

  In some cases, the function may be called on any node, and it can satisfactorily propagate to other nodes. That is true for schemadocstorelisten( integer, integer, integer ), for instance. In other cases, the function needs to be called on some particular node because that is the only place where data may be reasonably validated. For instance, schemadocsubscribeset( integer, integer, integer, boolean ) must be called on the receivernode.

- If that “main” function succeeds, then the configuration change is performed on the local node, and an event is created using schemadoccreateevent( name, text ) to cause the configuration change to propagate to all of the other nodes in the Slony-I cluster.

- Thirdly, the `_int` version of the function must be run.

  In some cases, where functions are idempotent, the node where the “main” function runs can do this fairly early in processing.

  When the event propagates, the other nodes will run the `_int` version, we rather hope with good success.