EV-Etcd

 view release on metacpan or  search on metacpan

etcd_common.c  view on Meta::CPAN

/*
 * etcd_common.c - Common utility functions for EV::Etcd
 */
#define PERL_NO_GET_CONTEXT
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#include "ppport.h"

#include <EV/EVAPI.h>

#include "etcd_common.h"

/* See etcd_common.h — defined here so all modules can tag fire-and-forget
 * batches (watch cancel send, keepalive renewal send). */
call_base_t cancel_sentinel = { CALL_TYPE_NONE };

/* gRPC status code names for error reporting - O(1) lookup table */
static const char * const grpc_status_names[] = {
    [GRPC_STATUS_OK] = "OK",
    [GRPC_STATUS_CANCELLED] = "CANCELLED",
    [GRPC_STATUS_UNKNOWN] = "UNKNOWN",
    [GRPC_STATUS_INVALID_ARGUMENT] = "INVALID_ARGUMENT",
    [GRPC_STATUS_DEADLINE_EXCEEDED] = "DEADLINE_EXCEEDED",
    [GRPC_STATUS_NOT_FOUND] = "NOT_FOUND",
    [GRPC_STATUS_ALREADY_EXISTS] = "ALREADY_EXISTS",
    [GRPC_STATUS_PERMISSION_DENIED] = "PERMISSION_DENIED",
    [GRPC_STATUS_RESOURCE_EXHAUSTED] = "RESOURCE_EXHAUSTED",
    [GRPC_STATUS_FAILED_PRECONDITION] = "FAILED_PRECONDITION",
    [GRPC_STATUS_ABORTED] = "ABORTED",
    [GRPC_STATUS_OUT_OF_RANGE] = "OUT_OF_RANGE",
    [GRPC_STATUS_UNIMPLEMENTED] = "UNIMPLEMENTED",
    [GRPC_STATUS_INTERNAL] = "INTERNAL",
    [GRPC_STATUS_UNAVAILABLE] = "UNAVAILABLE",
    [GRPC_STATUS_DATA_LOSS] = "DATA_LOSS",
    [GRPC_STATUS_UNAUTHENTICATED] = "UNAUTHENTICATED",
};
#define GRPC_STATUS_COUNT (sizeof(grpc_status_names) / sizeof(grpc_status_names[0]))

const char* grpc_status_name(grpc_status_code code) {
    if (code >= 0 && (size_t)code < GRPC_STATUS_COUNT && grpc_status_names[code]) {
        return grpc_status_names[code];
    }
    return "UNKNOWN_CODE";
}

/* Check if a status code is retryable */
int is_retryable_status(grpc_status_code code) {
    switch (code) {
        case GRPC_STATUS_UNAVAILABLE:
        case GRPC_STATUS_RESOURCE_EXHAUSTED:
        case GRPC_STATUS_ABORTED:
        case GRPC_STATUS_DEADLINE_EXCEEDED:
            return 1;
        default:
            return 0;
    }
}

/* Create error hashref for callbacks */
SV* create_error_hv(pTHX_ grpc_status_code code, const char *message, size_t message_len, const char *source) {
    HV *err = newHV();
    hv_store(err, "code", 4, newSViv(code), 0);
    hv_store(err, "status", 6, newSVpv(grpc_status_name(code), 0), 0);
    if (message && message_len > 0) {
        hv_store(err, "message", 7, newSVpvn(message, message_len), 0);
    } else {
        hv_store(err, "message", 7, newSVpv("", 0), 0);
    }
    hv_store(err, "source", 6, newSVpv(source, 0), 0);
    hv_store(err, "retryable", 9, newSViv(is_retryable_status(code)), 0);
    return newRV_noinc((SV *)err);
}

/* Convert KeyValue protobuf to Perl hashref */



( run in 1.367 second using v1.01-cache-2.11-cpan-bbc515a03b3 )