Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Blocking strategy response slower than expected #282

Open
Derkades opened this issue Apr 17, 2024 · 7 comments
Open

Blocking strategy response slower than expected #282

Derkades opened this issue Apr 17, 2024 · 7 comments
Labels
bug Something isn't working

Comments

@Derkades
Copy link

Describe the bug
I have configured sablier with nginx and whoami for testing. A response takes slightly over 5 seconds when the whoami container is not running. Even when starting the container manually, then issuing a request a few seconds later, it still takes 5 seconds. But the next request is instant again. I feel like there is some unnecessary delay somewhere.

Context

  • Sablier version: [e.g. 1.6.0] beta (052f7db)
  • Provider: [e.g. docker v20.10.21] Docker 26.0.1
  • Reverse proxy: [e.g. traefik v2.8.5] Nginx
  • Sablier running inside a container? Yes
@Derkades Derkades added the bug Something isn't working label Apr 17, 2024
@acouvreur
Copy link
Owner

Hello @Derkades is this issue still happening ?

@Derkades
Copy link
Author

Hi, yes it appears this is still an issue with the latest :beta

@acouvreur
Copy link
Owner

The first time sablier receives a request for a given container, it needs to check for its readiness.

So even if it's already running, the first request will be longer than the next ones.

Maybe I could pre-register all running containers, that could speed up things actually.

Would you be able to create a reproducible scenario with a docker compose file so I can experience this issue ?

@Derkades
Copy link
Author

Derkades commented Jul 2, 2024

Yes, thank you for your interest in solving this issue! This is my compose file:

services:
  sablier:
    image: ghcr.io/acouvreur/sablier:beta
    volumes:
      - type: bind
        source: ./sablier.yaml
        target: /etc/sablier/sablier.yml
      - type: bind
        source: /var/run/docker.sock
        target: /var/run/docker.sock
    ports: ['127.0.0.1:10000:10000']

  whoami:
    image: containous/whoami:v1.5.0
    labels:
      - sablier.enable=true
      - sablier.group=my-group

  nginx:
    image: nginxinc/nginx-unprivileged
    volumes:
      - type: bind
        source: ./nginx.conf
        target: /etc/nginx/nginx.conf
      - type: bind
        source: ./sablier.js
        target: /etc/nginx/conf.d/sablier.js
    ports: ['127.0.0.1:8080:8080']

And the sablier config file:

provider:
  name: docker
server:
  port: 10000
  base-path: /

Nginx configuration:

    server {
        listen 8080;
        # The internal location to reach sablier API
        set $sablierUrl /sablier;
        # Shared variable for default session duration
        set $sablierSessionDuration 30s;

        # internal location for sablier middleware
        # here, the sablier API is a container named "sablier" inside the same network as nginx
        location /sablier/ {
            internal;
            proxy_method GET;
            proxy_pass http://sablier:10000/;
        }

        # A named location that can be used by the sablier middleware to redirect
        location @whoami {
            # Use variable in order to refresh DNS cache
            set $whoami_server whoami;
            proxy_pass http://$whoami_server:80;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }

        # The actual location to match your API
        # Will answer by a waiting page or redirect to your app if
        # it is already up
        location /aa {
            # set $sablierDynamicShowDetails true;
            # set $sablierDynamicRefreshFrequency 5s;
            set $sablierNginxInternalRedirect @whoami;
            set $sablierGroup my-group;
            # set $sablierNames my-group;
            # set $sablierDynamicName "Dynamic Whoami";
            # set $sablierDynamicTheme ghost;
            set $sablierBlockingTimeout 10s;
            js_content sablier.call;
        }
    }

@acouvreur
Copy link
Owner

Thanks @Derkades!

Actually, I have found the issue:

ticker := time.NewTicker(5 * time.Second)

This checks every five seconds the readiness of the app.

I can try to change some core behavior to be more event driven. For docker I know that I can watch events, so I might just do that at some point.

I'll track this ticket for performance improvements. Note that, as always, performance improvement for Sablier always comes with you properly defining an healthcheck, otherwise Sablier cannot know the difference between started and ready to receive requests.

@Derkades
Copy link
Author

Derkades commented Jul 9, 2024

Hi, thanks for the update! Is the session request an expensive operation? It seems like it can be done much more often, say every 100 milliseconds. Before doing a more complex rewrite to an event-based system.

Thanks for the tip about defining a healthcheck, I'll keep that in mind when I start using it in production.

@acouvreur
Copy link
Owner

I'm planning on considerably enhancing communication with providers.

I'll use events instead of polling, meaning that we'll have real-time responses instead. I'll try to add that in the 1.8.0 release.
So you should see nice improvements.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants