Refactor API status reporting

Bug #418641 reported by Alex Yurchenko
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
wsrep API
Fix Released
High
Alex Yurchenko

Bug Description

Currently there is only one wsrep status variable that is accessible in application and it is last applied seqno. It is reported via callback to application on every update. However

1) It is an unnecessary overhead - this value is needed only by request. Overhead is small, but still unnecessary.
2) The callback needs to be called synchronously from a critical section to provide monotonic values, this makes it prone to a deadlock situation.
3) There are other status values to be reported, such as but not limited to: wsrep state (PRIM, non-PRIM, etc), state UUID, slave queue length, etc. - in other words thigns related to local provider performance.

Suggestion: substitute

    /*! datatypes for parameters */
    typedef enum wsrep_conf_param_type {
        WSREP_TYPE_INT, //!< integer type
        WSREP_TYPE_DOUBLE, //!< float
        WSREP_TYPE_STRING, //!< null terminated string
    } wsrep_conf_param_type_t;

    /*! statistic parameter identifiers */
    typedef enum wsrep_stat_param_id {
        WSREP_STAT_LAST_SEQNO, //!< last seqno applied
        WSREP_STAT_MAX
    } ;

    typedef void (*wsrep_stat_param_cb_t)(wsrep_stat_param_id_t,
                                          wsrep_conf_param_type_t,
                                          void* value);

with

    struct wsrep_status_report
    {
        <list of status parameters>
    }

    void wsrep_get_status (wsrep_t*, struct wsrep_status_report* status);

Application then calls wsrep_get_status only when it needs to know some or all status variables. E.g. mysql SHOW STATUS query may result in a wsrep_get_status() call.

Another possibility - return a dynamically allocated single-linked list of status variables:

    struct wsrep_status_var
    {
        struct wsrep_status_var* next;
        char* status_name;
        char* status_value;
    };

    struct wsrep_status_var* wsrep_status_get (wsrep_t*);

    void wsrep_status_free (struct wsrep_status_var*);

This has an advantage of having wsrep API totally independent of the number and types of status variables, but makes the processing of information more computationally intensive.

Related branches

tags: added: reporting status
Revision history for this message
Alex Yurchenko (ayurchen) wrote :

Now it looks like this:

/*! Type of the status variable value in struct wsrep_status_var */
typedef enum wsrep_var_type
{
    WSREP_STATUS_STRING, //!< pointer to null-terminated string
    WSREP_STATUS_INT64, //!< int64_t
    WSREP_STATUS_DOUBLE, //!< double
}
wsrep_var_type_t;

/*! Generalized status variable representation */
struct wsrep_status_var
{
    const char* name; //!< variable name
    wsrep_var_type_t type; //!< variable value type
    union {
        int64_t _int64;
        double _double;
        const char* _string;
    } value; //!< variable value
};

  /*!
   * @brief Returns an array fo status variables.
   * Array is terminated by Null variable name.
   *
   * @param wsrep this wsrep handle
   * @return array of struct wsrep_status_var
   */
    struct wsrep_status_var* (*status_get) (wsrep_t*);

On provider side:
static struct wsrep_status_var wsrep_status[] =
{
    {"state_uuid", WSREP_STATUS_STRING, {._string = state_uuid_str}},
    {"last_committed", WSREP_STATUS_INT64, { -1 } },
    {"replicated", WSREP_STATUS_INT64, { 0 } },
    {"replicated_bytes", WSREP_STATUS_INT64, { 0 } },
    {"received", WSREP_STATUS_INT64, { 0 } },
    {"received_bytes", WSREP_STATUS_INT64, { 0 } },
    {"local_commits", WSREP_STATUS_INT64, { 0 } },
    {"local_cert_failures", WSREP_STATUS_INT64, { 0 } },
    {"local_bf_aborts", WSREP_STATUS_INT64, { 0 } },
    {NULL, 0, { 0 }}
};

To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.