getting operation timed out when executed from NIF

I have a NIF function that executes a FFI function (pactffi from Release Pact FFI Library 0.4.19 · pact-foundation/pact-reference · GitHub).

static ERL_NIF_TERM verify_via_broker(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
{
    // if (!enif_is_binary(env, argv[0]))
    // {
    //     return enif_make_badarg(env);
    // }
    // char *name = convert_erl_binary_to_c_string(env, argv[0]);
    // if (!enif_is_binary(env, argv[1]))
    // {
    //     return enif_make_badarg(env);
    // }
    // char *scheme = convert_erl_binary_to_c_string(env, argv[1]);
    // if (!enif_is_binary(env, argv[2]))
    // {
    //     return enif_make_badarg(env);
    // }
    // char *host = convert_erl_binary_to_c_string(env, argv[2]);
    // if (!enif_is_number(env, argv[3]))
    // {
    //     return enif_make_badarg(env);
    // }
    // int port = convert_erl_int_to_c_int(env, argv[3]);
    // if (!enif_is_binary(env, argv[4]))
    // {
    //     return enif_make_badarg(env);
    // }
    // char *path = convert_erl_binary_to_c_string(env, argv[4]);

    // if (!enif_is_binary(env, argv[5]))
    // {
    //     return enif_make_badarg(env);
    // }
    // char *version = convert_erl_binary_to_c_string(env, argv[5]);

    // if (!enif_is_binary(env, argv[6]))
    // {
    //     return enif_make_badarg(env);
    // }
    // char *branch = convert_erl_binary_to_c_string(env, argv[6]);

    // if (!enif_is_binary(env, argv[7]))
    // {
    //     return enif_make_badarg(env);
    // }
    // char *broker_url = convert_erl_binary_to_c_string(env, argv[7]);

    // if (!enif_is_binary(env, argv[8]))
    // {
    //     return enif_make_badarg(env);
    // }
    // char *broker_username = convert_erl_binary_to_c_string(env, argv[8]);

    // if (!enif_is_binary(env, argv[9]))
    // {
    //     return enif_make_badarg(env);
    // }
    // char *broker_password = convert_erl_binary_to_c_string(env, argv[9]);

    // if (!enif_is_number(env, argv[10]))
    // {
    //     return enif_make_badarg(env);
    // }
    // int enable_pending = convert_erl_int_to_c_int(env, argv[10]);

    // if (!enif_is_binary(env, argv[11]))
    // {
    //     return enif_make_badarg(env);
    // }
    // char *consumer_version_selectors = convert_erl_binary_to_c_string(env, argv[11]);

    // if (!enif_is_number(env, argv[12]))
    // {
    //     return enif_make_badarg(env);
    // }
    // int consumer_version_selectors_len = convert_erl_int_to_c_int(env, argv[12]);

    // if (!enif_is_binary(env, argv[13]))
    // {
    //     return enif_make_badarg(env);
    // }
    // char *protocol = convert_erl_binary_to_c_string(env, argv[13]);

    // ErlNifPid pid;

    // enif_get_local_pid(env, argv[14], &pid);

    // if (!enif_is_binary(env, argv[15]))
    // {
    //     return enif_make_badarg(env);
    // }
    // char *state_path = convert_erl_binary_to_c_string(env, argv[15]);


    char *name = "animal_service";
    char *scheme = "http";
    char *host = "localhost";
    int port = 8080;
    char *path = "/";
    char *version = "default";
    char *branch = "develop";
    char *broker_url = "http://localhost:9292/";
    // OSS pact broker docker image: pactfoundation/pact-broker
    char *broker_username = "pact_workshop";
    char *broker_password = "pact_workshop";
    int enable_pending = 1;
    char *consumer_version_selectors = "{}";
    int consumer_version_selectors_len = 0;
    char *protocol = "http";

    
    char *state_path = "http://localhost:8080/pactStateChange";

    struct VerifierHandle *verifierhandle;
    verifierhandle = pactffi_verifier_new_for_application(name, version);
    pactffi_verifier_set_provider_info(verifierhandle, name, scheme, host, port, path);
    pactffi_verifier_add_provider_transport(verifierhandle, protocol, port, path, scheme);

    if (state_path[0] != '\0')
    {
        pactffi_verifier_set_provider_state(verifierhandle, state_path, 0, 1);
    }
    pactffi_verifier_set_verification_options(verifierhandle, 0, 5000),
    pactffi_verifier_set_publish_options(verifierhandle, version, NULL, NULL, -1, branch);
    pactffi_verifier_broker_source_with_selectors(verifierhandle, broker_url, broker_username, broker_password, NULL, enable_pending, NULL, NULL, -1, branch, consumer_version_selectors, consumer_version_selectors_len, NULL, -1);
    setenv("PACT_DO_NOT_TRACK", "true", 1);


    // ErlDrvTid tid;
    // ErlDrvThreadOpts *opts = erl_drv_thread_opts_create("example_thread");



    // // Create a new thread
    // if (erl_drv_thread_create("example_thread", &tid, ranjan_function, &verifierhandle, opts) != 0) {
    //     // fprintf(stderr, "Failed to create thread\n");
    //     return 1;
    // }


    // int *result;
    // if (erl_drv_thread_join(tid, (void **)&result) != 0) {
    //     // fprintf(stderr, "Failed to join thread\n");
    //     return 1;
    // }

    // printf("Result returned by the thread: %d\n", *result);

    // // Detach the thread (optional)
    // if (erl_drv_thread_detach(tid) != 0) {
    //     fprintf(stderr, "Failed to detach thread\n");
    //     return 1;
    // }

    int output = pactffi_verifier_execute(verifierhandle);


    pactffi_verifier_shutdown(verifierhandle);


    // ERL_NIF_TERM message = enif_make_int(env, output);

    // enif_send(env, &pid, NULL, message);

    return enif_make_int(env, output);
}

What this code does is when it sends requests to a localhost:8080/pactStateChange in the int output = pactffi_verifier_execute(verifierhandle);

Now when I try to execute the above FFI via NIF erlang function, I can only execute this if I execute it from another erlang shell but not from the same shell where the http server is started which listens on localhost:8080/pactStateChange.

What could be the reason for this?

PFA logs of the pactffi:

2024-04-17T10:57:48.373523Z DEBUG ThreadId(01) verify_interaction{interaction="a request to GET a non-existing animal: Miles"}: pact_verifier::provider_client: State change request failed with error error sending request for url (http://localhost:8080/pactStateChange): operation timed out
2024-04-17T10:57:48.373940Z DEBUG ThreadId(01) verify_interaction{interaction="a request to GET a non-existing animal: Miles"}: pact_verifier: State Change: "ProviderState { name: "", params: {} }" -> Err(Provider state failed: (interaction_id: 89d5c01cb84b83b5eaf9b413ff1add3c019f90af) Invalid response: error sending request for url (http://localhost:8080/pactStateChange): operation timed out)
2024-04-17T10:57:48.373986Z ERROR ThreadId(01) verify_interaction{interaction="a request to GET a non-existing animal: Miles"}: pact_verifier: Provider setup state change for has failed - MismatchResult::Error("Invalid response: error sending request for url (http://localhost:8080/pactStateChange): operation timed out", Some("89d5c01cb84b83b5eaf9b413ff1add3c019f90af"))
2024-04-17T10:57:48.528450Z DEBUG ThreadId(01) verify_interaction{interaction="a request to create an animal: Max"}: pact_verifier: Executing provider states
1 Like

@srijan