Skip to content

Immediate, infinite recursion when configuration loader is set to boot and reloading is disabled #1467

@coderbydesign

Description

@coderbydesign

With the fix in #1399, it appears there was a regression introduced when using the following configuration, which is a use case where you'd want to load the configuration at boot, and never reload:

# load configuration at boot
APICAST_CONFIGURATION_LOADER: boot

# disable configuration refresh
APICAST_CONFIGURATION_CACHE:  -1

Prior to the fix for the above bug, the only way the configuration_loader executed the schedule method was if interval > 0 then, which would then refresh the configuration at whatever positive interval was defined in APICAST_CONFIGURATION_CACHE.

The changes introduced here make it so that even when you have refresh disabled via a negative number as documented here, this logic will always call the schedule method, and ultimately ngx.timer.at with a delay of -1 because the schedule method is recursive and uses the ttl, which will cause the timer to expire immediately (the same as a 0 value delay which is not an edge-case seen in APIcast since that's not valid with boot configuration) executing the callback immediately, and infinitely reloading the configuration.

This ultimately causes CPU and other resource consumption issues, and when done remotely has network and request implications trying to fetch the config.

Version
nginx version: openresty/1.21.4.3
quay.io/3scale/apicast-ci:openresty-1.21.4-1: 2024-04-29T20:39:47.030811444+10:00
Steps To Reproduce
  1. make development
  2. make dependencies
  3. Ensure this config [1] exists at /opt/app-root/src/config.json
  4. Run APICAST_LOG_LEVEL=info APICAST_WORKERS=1 THREESCALE_PORTAL_ENDPOINT=http://echo:8081/config/ THREESCALE_CONFIG_FILE=/opt/app-root/src/config.json APICAST_CONFIGURATION_LOADER=boot APICAST_CONFIGURATION_CACHE=-1 THREESCALE_DEPLOYMENT_ENV=staging APICAST_SERVICES_LIST=1234 ./bin/apicast
Current Result

You'll see that after the initial boot configuration loads, it then enters into the scheduler, and immediately and infinitely starts refreshing the configuration. Here is a sample of the output: https://gist.github.com/coderbydesign/f3d95680b27a34795c58e9906e784d71

Expected Result

We see the environment config loaded once at boot, with no schedule set for reloading configuration: https://gist.github.com/coderbydesign/0421cd55635007f3f45361eb6c35ee48

Additional Information

Thanks to @dagbay-rh for finding the initial root cause of our issue and helping here!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions