\label{doc_decisions_0_drafts_commit_function_md_md_doc_decisions_0_drafts_commit_function}%
\Hypertarget{doc_decisions_0_drafts_commit_function_md_md_doc_decisions_0_drafts_commit_function}%
 \hypertarget{doc_decisions_0_drafts_commit_function_md_autotoc_md1717}{}\doxysection{Problem}\label{doc_decisions_0_drafts_commit_function_md_autotoc_md1717}
When {\ttfamily \mbox{\hyperlink{group__kdb_ga11436b058408f83d303ca5e996832bcf}{kdb\+Set()}}} is called, plugins implementing the commit role, need to internally track their state to distinguish between carrying out that role and carrying out potential other roles (commit and setresolver for the resolver plugin, for example). This limits the possibilities of plugin reuse and the ways plugins can be combined.

More generally, this problem applies to all plugins with one function that is called multiple times for different reasons.

Between {\ttfamily libelektra-\/kdb} and a backend plugins there is a \mbox{\hyperlink{doc_dev_backend-plugins_md}{contract}} that uses \char`\"{}phases\char`\"{} for this.

With the introduction of the new backend, a new {\ttfamily kdb\+Commit} function was introduced to {\ttfamily struct \+\_\+\+Plugin} (matching {\ttfamily kdb\+Error}). We also added a {\ttfamily kdb\+Init}. Therefore, some phases of {\ttfamily kdb\+Get}/{\ttfamily kdb\+Set} now use separate functions, but not all of them do. This partial use of separate functions can be weird and unintuitive.\hypertarget{doc_decisions_0_drafts_commit_function_md_autotoc_md1718}{}\doxysection{Constraints}\label{doc_decisions_0_drafts_commit_function_md_autotoc_md1718}

\begin{DoxyItemize}
\item Plugins should not have internal state that tracks how often a function has been called to determine what the function should do next.
\end{DoxyItemize}\hypertarget{doc_decisions_0_drafts_commit_function_md_autotoc_md1719}{}\doxysection{Assumptions}\label{doc_decisions_0_drafts_commit_function_md_autotoc_md1719}
\hypertarget{doc_decisions_0_drafts_commit_function_md_autotoc_md1720}{}\doxysection{Considered Alternatives}\label{doc_decisions_0_drafts_commit_function_md_autotoc_md1720}

\begin{DoxyEnumerate}
\item Keep the current \char`\"{}partial separation\char`\"{} approach.

So far, there has been no technical reason why some phases use separate functions and others do not. At least there has been no explanation, why separate {\ttfamily kdb\+Commit}/{\ttfamily kdb\+Error} would be better than having some other way of knowing the phase.
\item Fully separate the functions with one function for each of the phases {\ttfamily libelektra-\/kdb} knows.

This would introduce a lot of symbols, which would bloat {\ttfamily struct \+\_\+\+Plugin}. The bloat could be avoided by choosing the approach in the \mbox{\hyperlink{doc_decisions_0_drafts_plugin_contract_function_md}{Plugin Contract Function}}Plugin Contract Function\char`\"{}\char`\"{} decision that removes the function pointers from {\ttfamily struct \+\_\+\+Plugin}.
\item Only use {\ttfamily kdb\+Open}, {\ttfamily kdb\+Get}, {\ttfamily kdb\+Set} and {\ttfamily kdb\+Close} functions matching the ones in {\ttfamily libelektra-\/kdb}. Communicate the current phase via the {\ttfamily elektra\+Plugin\+Get\+Phase} function.

Matching the functions from {\ttfamily libelektra-\/kdb} makes it clear, which plugin function gets used for which {\ttfamily kdb$\ast$} call. The API does not make it obvious that phases exist. Plugins that handle multiple phases must call {\ttfamily elektra\+Plugin\+Get\+Phase} to know what phase is being executed. Also using a single {\ttfamily elektra\+Plugin\+Get\+Phase} function means all phases must share a single type, even if not all phases are shared between {\ttfamily kdb\+Get} and {\ttfamily kdb\+Set}.
\item Like 3, but instead of using a {\ttfamily elektra\+Plugin\+Get\+Phase} function, directly pass a {\ttfamily Elektra\+Get\+Phase phase}/{\ttfamily Elektra\+Set\+Phase phase} parameter.

This API makes it very clear that phases exist and that the plugin might need to handle them. It also allows using separate types for the phases of {\ttfamily kdb\+Get} and {\ttfamily kdb\+Set}. However, a big downside of this approach is that it adds an extra parameter to the API that will be unused by many plugins.

This API also allows plugins to call other plugins to execute a different phase. This could be a good thing or a bad thing.
\end{DoxyEnumerate}\hypertarget{doc_decisions_0_drafts_commit_function_md_autotoc_md1721}{}\doxysection{Decision}\label{doc_decisions_0_drafts_commit_function_md_autotoc_md1721}
\hypertarget{doc_decisions_0_drafts_commit_function_md_autotoc_md1722}{}\doxysection{Rationale}\label{doc_decisions_0_drafts_commit_function_md_autotoc_md1722}
\hypertarget{doc_decisions_0_drafts_commit_function_md_autotoc_md1723}{}\doxysection{Implications}\label{doc_decisions_0_drafts_commit_function_md_autotoc_md1723}
\hypertarget{doc_decisions_0_drafts_commit_function_md_autotoc_md1724}{}\doxysection{Related Decisions}\label{doc_decisions_0_drafts_commit_function_md_autotoc_md1724}

\begin{DoxyItemize}
\item \mbox{\hyperlink{doc_decisions_0_drafts_plugin_contract_function_md}{Plugin Contract Function}}
\item \mbox{\hyperlink{doc_decisions_0a_postponed_plugin_struct_md}{Plugin Struct}}
\end{DoxyItemize}\hypertarget{doc_decisions_0_drafts_commit_function_md_autotoc_md1725}{}\doxysection{Notes}\label{doc_decisions_0_drafts_commit_function_md_autotoc_md1725}
