a year ago
I have the following NestJs service:
import { Injectable, Logger, OnModuleInit } from '@nestjs/common';
import { Redis } from 'ioredis';
import { EnvService } from 'src/env/env.service';
@Injectable()
export class RedisService extends Redis implements OnModuleInit {
private readonly logger = new Logger(RedisService.name);
public readonly redisUrl = this.envService.get('REDIS_URL');
public readonly redisProtocol = this.envService.get('REDIS_PROTOCOL');
constructor(private readonly envService: EnvService) {
const redisUrl = envService.get('REDIS_URL');
const redisProtocol = envService.get('REDIS_PROTOCOL');
super(redisUrl, {
family: redisProtocol,
maxRetriesPerRequest: null,
connectTimeout: 30000, // 30 seconds
});
this.redisUrl = redisUrl;
this.redisProtocol = redisProtocol;
this.logger.log('creating redis client', redisUrl, redisProtocol);
}
async onModuleInit(): Promise {
await new Promise((resolve, reject) => {
this.logger.log('connecting to redis...');
this.on('connect', () => {
this.logger.log('connected to redis');
resolve();
});
this.on('error', (error) => {
this.logger.error('Error connecting to Redis:', error);
reject(error);
});
});
}
}
In the Deploy Logs it prints the following values:
[Nest] 25 - 02/27/2024, 2:52:04 PM LOG [RedisService] creating redis client
[Nest] 25 - 02/27/2024, 2:52:04 PM LOG [RedisService] redis://default:BMdLME2HPo6igkB4bpgGHMMiA21MBiBI@redis-eblx.railway.internal:6379
[Nest] 25 - 02/27/2024, 2:52:04 PM LOG [RedisService] 6
[Nest] 25 - 02/27/2024, 2:52:09 PM ERROR [RedisService] Error connecting to Redis:
[Nest] 25 - 02/27/2024, 2:52:09 PM ERROR [RedisService] Error: getaddrinfo ENOTFOUND redis-eblx.railway.internal
Any idea on what I am doing wrong?
1 Replies
a year ago
please have a look at this docs section
I see this in the docs
ioredis is a Redis client for node.js, commonly used for connecting to Redis from a node application. When initializing a Redis client using ioredis, you must specify family=0 in the connection string to support connecting to both IPv6 and IPv4 connections:
import Redis from 'ioredis';
const redis = new Redis(process.env.REDISPRIVATEURL + '?family=0');
const ping = await redis.ping();
When I update my constructor to the following it unfortunately still doesn't work.
constructor(private readonly envService: EnvService) {
const redisProtocol = envService.get('REDIS_PROTOCOL');
const redisUrl = `${envService.get('REDIS_URL')}?family=${redisProtocol}`;
super(redisUrl, {
maxRetriesPerRequest: null,
connectTimeout: 30000, // 30 seconds
});
this.redisUrl = redisUrl;
this.redisProtocol = redisProtocol;
this.logger.log('creating redis client', redisUrl, redisProtocol);
}
Logs:
[Nest] 26 - 02/27/2024, 3:34:13 PM LOG [RedisService] creating redis client
[Nest] 26 - 02/27/2024, 3:34:13 PM LOG [RedisService] redis://default:BMdLME2HPo6igkB4bpgGHMMiA21MBiBI@redis-eblx.railway.internal:6379?family=0
[Nest] 26 - 02/27/2024, 3:34:13 PM LOG [RedisService] 0
[Nest] 25 - 02/27/2024, 3:34:41 PM ERROR [RedisService] Error connecting to Redis:
[Nest] 25 - 02/27/2024, 3:34:41 PM ERROR [RedisService] Error: getaddrinfo ENOTFOUND redis-eblx.railway.internal
a year ago
looks like you are complicating things quite a bit, just try setting family to 0 in the options object please
a year ago
are you deploying with nixpacks?
a year ago
okay cool, please try my suggestion
When I do "const redisUrl = envService.get('REDIS_URL') + '?family=0';" it works, you right. Not sure why, it logs the same
a year ago
awsome!
a year ago
typo?
When I use a text compare tool it is the same. No idea, I don't really have the time to look into it at the moment. Thanks a lot!
a year ago
no problem!
a year ago
okay can you add a 3 second sleep to your start script as to delay the starting of your app
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { EnvService } from './env/env.service';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
const envService = app.get(EnvService);
app.enableCors();
await app.listen(envService.get('PORT'));
}
bootstrap();
Before NestFactory.create or after?
a year ago
please add the sleep in the start script, theres really no need to overcomplicate the solutions im trying to provide 🫤
Ah, I think you mean here like this
"start:prod": "sleep 3 && node dist/main"
I am not over-complicating it on purpose. I am unsure what a "start script" is from your perspective. The package.json script, the code initializing the application, etc.
a year ago
thats correct
a year ago
the private network's dns resolver takes about 3 seconds to start answering lookup requests, though its still only ipv6, so you do need family: 0
still
Ok, thanks you, interesting. Even after multiple restarts it is working. I will increase it to 5 seconds just to be sure
a year ago
i dont think theres a need for 5 seconds, over a 7 day period the slowest resolver ready time was only ~2.3 seconds
Interesting stats, very good to know. Now the private networking is solid. Thanks for the patience, I highly appreciate it <:salute:1137099685417451530>
a year ago
no problem! and for the record the team is working to remove any and all startup delays
a year ago
less help threads for me too, though it wont solve the need for the family 0 config
a year ago
thats something ioredis really should change, since it currently defaults to ipv4 only (family 4)
Yeah, I had it on family 6, which did work once, but then after another redeploy it didn't work and I though I had introduced a bug, but seems like the sleep was missing. Ipv6 generally still feels like a earlier adopter thing or like an afterthought, which is ridiculous
a year ago
Just came across this same issue with ioredis and solved by setting family=0, thanks!
Just for clarification to anyone else who finds this, the family
option can take one of the following values:
4
: Use IPv4 protocol family. (default)6
: Use IPv6 protocol family.0
: Let the operating system decide which protocol family to use.