HRESULT H_FABRIC_API()

in sfwrapper/inc/h_fabric_macro_generator.h [214:299]


HRESULT H_FABRIC_API(IFABRIC_METHOD_NAME)(H_FABRIC_HANDLE(IFABRIC_INTERFACE_NAME) handle                                                                                                    \
    ARGS_C_DECLARATION(in_args)                                                                                                                                                             \
)                                                                                                                                                                                           \
{                                                                                                                                                                                           \
    HRESULT hr; /*also used a result*/                                                                                                                                                      \
    /*Codes_SRS_H_FABRIC_MACRO_GENERATOR_02_007: [ If handle is NULL then H_FABRIC_API(IFABRIC_METHOD_NAME) shall fail and return NULL. ]*/                                                 \
    if (handle == NULL)                                                                                                                                                                     \
    {                                                                                                                                                                                       \
        LogError("invalid " MU_TOSTRING(HANDLE_TYPE) " handle=%p", handle);                                                                                                                 \
        hr = E_POINTER;                                                                                                                                                                     \
    }                                                                                                                                                                                       \
    else                                                                                                                                                                                    \
    {                                                                                                                                                                                       \
        /*Codes_SRS_H_FABRIC_MACRO_GENERATOR_02_008: [ H_FABRIC_API(IFABRIC_METHOD_NAME) shall record the start time of the request by calling timer_global_get_elapsed_ms. ]*/             \
        double startTime = timer_global_get_elapsed_ms(); /*time spend here cannot exceed timeoutMilliseconds*/                                                                             \
        double elapsed;                                                                                                                                                                     \
        uint32_t retries = 0; /*incremented at every API call - 0 means "it will call once", "1" means it will call 2 times". It is in the name: **re**tries.*/                             \
                                                                                                                                                                                            \
        do                                                                                                                                                                                  \
        {                                                                                                                                                                                   \
            /*Codes_SRS_H_FABRIC_MACRO_GENERATOR_02_009: [ H_FABRIC_API(IFABRIC_METHOD_NAME) shall call IFABRIC_METHOD_NAME on the instance of IFABRIC_INTERFACE_NAME. ]*/                  \
            hr = IFABRIC_METHOD_NAME(handle->This ARGS_C_CALL(in_args));                                                                                                                    \
            if (FAILED(hr))                                                                                                                                                                 \
            {                                                                                                                                                                               \
                LogHRESULTError(hr, "failure in " MU_TOSTRING(IFABRIC_METHOD_NAME) "(handle->This=%p, ...)",                                                                                \
                    handle->This);                                                                                                                                                          \
                                                                                                                                                                                            \
                /*Codes_SRS_H_FABRIC_MACRO_GENERATOR_02_011: [ If the result is FABRIC_E_OBJECT_CLOSED, FABRIC_E_GATEWAY_NOT_REACHABLE, FABRIC_E_TIMEOUT or E_ABORT then H_FABRIC_API(IFABRIC_METHOD_NAME) shall create a new instance of IFABRIC_INTERFACE_NAME. ]*/ \
                /* FABRIC_E_TIMEOUT was observed in certain cases, such as RestartPartition. We should retry by creating a new client and trying the call again, */                         \
                /* up to the timeout specified in the H_FABRIC_HANDLE. */                                                                                                                   \
                if ((hr == E_ABORT) || (hr == FABRIC_E_OBJECT_CLOSED) || (hr == FABRIC_E_GATEWAY_NOT_REACHABLE) || (hr == FABRIC_E_TIMEOUT))                                                \
                {                                                                                                                                                                           \
                    IFABRIC_INTERFACE_NAME* newInstance = NULL;                                                                                                                             \
                                                                                                                                                                                            \
                    HRESULT hr_create;                                                                                                                                                      \
                    hr_create = CREATE_IFABRICINSTANCE_NAME(IFABRIC_INTERFACE_NAME)(&newInstance);                                                                                          \
                    if (FAILED(hr_create))                                                                                                                                                  \
                    {                                                                                                                                                                       \
                        /*Codes_SRS_H_FABRIC_MACRO_GENERATOR_02_012: [ If creating the new instance of IFABRIC_INTERFACE_NAME fails then H_FABRIC_API(IFABRIC_METHOD_NAME) shall retry using the existing IFABRIC_INTERFACE_NAME. ]*/ \
                        LogHRESULTError(hr_create, "failure in CREATE_IFABRICINSTANCE_NAME(" MU_TOSTRING(IFABRIC_INTERFACE_NAME) ")(&newInstance=%p)", &newInstance);                       \
                        /*keep retrying until timeout*/                                                                                                                                     \
                    }                                                                                                                                                                       \
                    else                                                                                                                                                                    \
                    {                                                                                                                                                                       \
                        /*Codes_SRS_H_FABRIC_MACRO_GENERATOR_02_013: [ Otherwise H_FABRIC_API(IFABRIC_METHOD_NAME) shall release the existing instance and shall retry using new newly created IFABRIC_INTERFACE_NAME. ]*/ \
                        /*let go of the old instance*/                                                                                                                                      \
                        (void)handle->This->lpVtbl->Release(handle->This);                                                                                                                  \
                                                                                                                                                                                            \
                        /*replace it with the new instance*/                                                                                                                                \
                        handle->This = newInstance;                                                                                                                                         \
                    }                                                                                                                                                                       \
                }                                                                                                                                                                           \
                else if (0 RESULTS_CHECK(permanent_failures))                                                                                                                               \
                {                                                                                                                                                                           \
                    /*Codes_SRS_H_FABRIC_MACRO_GENERATOR_42_001: [ If the result is any value from permanent_failures then H_FABRIC_API(IFABRIC_METHOD_NAME) shall return. ]*/              \
                    break;                                                                                                                                                                  \
                }                                                                                                                                                                           \
                else                                                                                                                                                                        \
                {                                                                                                                                                                           \
                    /*Codes_SRS_H_FABRIC_MACRO_GENERATOR_02_014: [ If the result is any other value except FABRIC_E_OBJECT_CLOSED, FABRIC_E_GATEWAY_NOT_REACHABLE or E_ABORT then H_FABRIC_API(IFABRIC_METHOD_NAME) shall retry. ]*/ \
                    /*some other HRESULT, so retry without re-creating the object*/                                                                                                         \
                }                                                                                                                                                                           \
            }                                                                                                                                                                               \
            else                                                                                                                                                                            \
            {                                                                                                                                                                               \
                /*Codes_SRS_H_FABRIC_MACRO_GENERATOR_02_010: [ If the call succeeds then H_FABRIC_API(IFABRIC_METHOD_NAME) shall succeed and return. ]*/                                    \
                break;                                                                                                                                                                      \
            }                                                                                                                                                                               \
                                                                                                                                                                                            \
            /*Codes_SRS_H_FABRIC_MACRO_GENERATOR_02_015: [ H_FABRIC_API(IFABRIC_METHOD_NAME) shall sleep msBetweenRetries. ]*/                                                              \
            ThreadAPI_Sleep(handle->msBetweenRetries);                                                                                                                                      \
            retries++;                                                                                                                                                                      \
            elapsed = timer_global_get_elapsed_ms() - startTime;                                                                                                                            \
                                                                                                                                                                                            \
            /*Codes_SRS_H_FABRIC_MACRO_GENERATOR_02_016: [ If the total time spend retrying exceeds timeoutMilliseconds then H_FABRIC_API(IFABRIC_METHOD_NAME) shall return the last error code. ]*/ \
            /*Codes_SRS_H_FABRIC_MACRO_GENERATOR_02_017: [ If the total number of retries exceeds nMaxRetries then H_FABRIC_API(IFABRIC_METHOD_NAME) shall return the last error code. ]*/  \
        } while ((retries < handle->nMaxRetries) && (elapsed < timeoutMilliseconds));                                                                                                       \
                                                                                                                                                                                            \
        if(FAILED(hr))                                                                                                                                                                      \
        {                                                                                                                                                                                   \
            LogHRESULTError(hr, "tried for %" PRIu32 " times in %" PRIu32 "[ms] and it failed", retries, timeoutMilliseconds);                                                              \
        }                                                                                                                                                                                   \
    }                                                                                                                                                                                       \
                                                                                                                                                                                            \
    return hr;                                                                                                                                                                              \
}