anycable / anycable-go

AnyCable real-time server
https://anycable.io
MIT License
377 stars 65 forks source link

Support redis socket url? #198

Open sebyx07 opened 12 months ago

sebyx07 commented 12 months ago

Ruby supports pointing the path to the redis server,

ENV["REDIS_PATH"] ||= Rails.root.join("tmp", "redis", "redis.sock").to_s

redis_config = {
  path: ENV["REDIS_PATH"],
}

is it possible for anycable to support it as well? the use case is: have an development enviroment with docker/docker-compose, where services like postgres, redis don't polute the localhost ports, and just listen to a socket file

palkan commented 12 months ago

@ardecvz any thoughts? (you're the last one who touched Redis configuration code 🙂)

palkan commented 11 months ago

Hey again,

It looks like connecting to Unix Redis socket is already supported (since 1.4.5). You should be able to use unix://tmp/redis/redis.sock as the REDIS_URL value. Please, let me know if it works or not (and we'll re-open it if there are some problems).

ardecvz commented 11 months ago

@palkan We should consider reopening this issue because Unix socket support is currently broken. The problem lies in the upstream Redis library, specifically this line, where it checks for path parts and fails if there are more than two. This check affects URLs like unix://tmp/my/redis.sock or unix://tmp/redis.sock or unix:///redis.sock (3 slashes), but it should work correctly for unix://redis.sock.

@sebyx07 please, use the last form if immediate support is required. We can also upgrade the Redis library if you're interested to fix this behaviour in the upstream.

lcmen commented 6 months ago

@ardecvz I might be wrong but I believe the problem is not with slashes. No matter how many slashes I use in --redis_url option or REDIS_URL env var, it always complain about invalid URL scheme (I tried both: unix://tmp/my/redis.sock and unix://redis.sock).

It seems a bit strange as according to rueidis source code, version 1.0.26 (used by the latest version anycable-go which is 1.5.1 at the time of writing this comment) supports unix scheme.

@palkan any idea?

palkan commented 6 months ago

Hey @lcmen,

Can you please post the full output with the error?

lcmen commented 6 months ago

@palkan here it is:

2024-05-20 20:48:18.312 INF Handle WebSocket connections at http://localhost:8080/cable nodeid=pW2KoC
2024-05-20 20:48:18.312 INF Handle health requests at http://localhost:8080/health nodeid=pW2KoC
2024-05-20 20:48:18.312 WRN Redis connection failed nodeid=pW2KoC context=broadcast provider=redis error="invalid redis URL scheme: unix"
2024-05-20 20:48:18.312 INF next Redis reconnect attempt in 2s nodeid=pW2KoC context=broadcast provider=redis
ardecvz commented 6 months ago

@lcmen Hey 👋 Thanks for the heads-up! The Unix socket support in Ruedis is indeed added here.

I've also tested the integration - it's broken by default 😢

However, it's broken only for the backward-compatible Redis setup with pub/sub (--broadcast_adapter redis). If you switch to a new one based on Ruedis, it works fine (--broadcast_adapter redisx). The Pubsub component also works as it uses Ruedis.

Therefore, you could use it right now - just don't forget to switch to it in the Rails app too (broadcast_adapter: redisx in config/anycable.yml).

More details here in the Go part and here in the Rails one.

P.S.: you're likely interested in a new adapter for new app setups anyway to use a broker to keep persistent history.

It seems that the old Redis lib Redigo also supports Unix sockets so I could patch the default broadcaster too if @palkan hasn't done it already and is OK with the plan?

palkan commented 6 months ago

It seems that the old Redis lib Redigo also https://github.com/gomodule/redigo/pull/669 so I could patch the default broadcaster too if @palkan hasn't done it already and is OK with the plan?

Let's do that!

lcmen commented 6 months ago

Thanks @ardecvz for very informative summary.

One question: if I switch to redisx as broadcast adapter does it mean I will be automatically using redis streams instead of pub/sub? Is there a way to use pub/sub with redisx adapter?

palkan commented 6 months ago

Is there a way to use pub/sub with redisx adapter?

Nope, these are different adapters.

Pub/sub Redis is to be deprecated in v2.0; that's why it's still relying on a different Redis library.

You can migrate to RedisX and use streams or even use HTTP adapter with Redis internal pub/sub (i.e., anycable-go -pubsub=redis).

lcmen commented 6 months ago

Thank you for clarification. We will switch to streams!