Enhance Redis connection handling with retry logic and improved error logging

This commit is contained in:
Arunavo Ray
2025-05-19 11:08:49 +05:30
parent 05e999cfa1
commit 8f1b97f35b
3 changed files with 151 additions and 4 deletions

124
README.md
View File

@@ -283,7 +283,8 @@ For full end-to-end testing, you can set up a local Gitea instance using Docker:
```bash
# Create a Docker network for Gitea and Gitea Mirror to communicate
docker network create gitea-network
# Using the --label flag ensures proper Docker Compose compatibility
docker network create --label com.docker.compose.network=gitea-network gitea-network
# Create volumes for Gitea data persistence
docker volume create gitea-data
@@ -396,6 +397,127 @@ This project is now complete and ready for production use with version 1.0.0. Al
- ✅ Light/dark mode toggle
- ✅ Persistent configuration storage
## Troubleshooting
### Docker Compose Network Issues
If you encounter network-related warnings or errors when running Docker Compose, such as:
```
WARN[0095] a network with name gitea-network exists but was not created by compose.
Set `external: true` to use an existing network
```
or
```
network gitea-network was found but has incorrect label com.docker.compose.network set to "" (expected: "gitea-network")
```
Try the following steps:
1. Stop the current Docker Compose stack:
```bash
docker compose -f docker-compose.dev.yml down
```
2. Remove the existing network:
```bash
docker network rm gitea-network
```
3. Restart the Docker Compose stack:
```bash
docker compose -f docker-compose.dev.yml up -d
```
If you need to share the network with other Docker Compose projects, you can modify the `docker-compose.dev.yml` file to mark the network as external:
```yaml
networks:
gitea-network:
name: gitea-network
external: true
```
### Redis Connection Issues
If the application fails to connect to Redis with errors like `ECONNREFUSED 127.0.0.1:6379`, ensure:
1. The Redis container is running:
```bash
docker ps | grep redis
```
2. The `REDIS_URL` environment variable is correctly set to `redis://redis:6379` in your Docker Compose file.
3. Both the application and Redis containers are on the same Docker network.
4. If running without Docker Compose, ensure you've started a Redis container and linked it properly:
```bash
# Start Redis container
docker run -d --name gitea-mirror-redis redis:alpine
# Run application with link to Redis
docker run -d -p 4321:4321 --link gitea-mirror-redis:redis \
-e REDIS_URL=redis://redis:6379 \
ghcr.io/arunavo4/gitea-mirror:latest
```
#### Improving Redis Connection Resilience
For better Redis connection handling, you can modify the `src/lib/redis.ts` file to include retry logic and better error handling:
```typescript
import Redis from "ioredis";
// Connect to Redis using REDIS_URL environment variable or default to redis://redis:6379
const redisUrl = process.env.REDIS_URL ?? 'redis://redis:6379';
console.log(`Connecting to Redis at: ${redisUrl}`);
// Configure Redis client with connection options
const redisOptions = {
retryStrategy: (times) => {
// Retry with exponential backoff up to 30 seconds
const delay = Math.min(times * 100, 3000);
console.log(`Redis connection attempt ${times} failed. Retrying in ${delay}ms...`);
return delay;
},
maxRetriesPerRequest: 5,
enableReadyCheck: true,
connectTimeout: 10000,
};
export const redis = new Redis(redisUrl, redisOptions);
export const redisPublisher = new Redis(redisUrl, redisOptions);
export const redisSubscriber = new Redis(redisUrl, redisOptions);
// Log connection events
redis.on('connect', () => console.log('Redis client connected'));
redis.on('error', (err) => console.error('Redis client error:', err));
```
This implementation provides:
- Automatic retry with exponential backoff
- Better error logging
- Connection event handling
- Proper timeout settings
### Container Health Checks
If containers are not starting properly, check their health status:
```bash
docker ps --format "{{.Names}}: {{.Status}}"
```
For more detailed logs:
```bash
docker logs gitea-mirror-dev
```
## Acknowledgements
- [Octokit](https://github.com/octokit/rest.js/) - GitHub REST API client for JavaScript

View File

@@ -108,3 +108,6 @@ volumes:
networks:
gitea-network:
name: gitea-network
# Let Docker Compose manage this network
# If you need to use an existing network, uncomment the line below
# external: true

View File

@@ -1,8 +1,30 @@
import Redis from "ioredis";
// Connect to Redis using REDIS_URL environment variable or default to redis://redis:6379
// This ensures we have a fallback URL when running with Docker Compose
const redisUrl = process.env.REDIS_URL ?? 'redis://redis:6379';
export const redis = new Redis(redisUrl);
export const redisPublisher = new Redis(redisUrl); // For publishing
export const redisSubscriber = new Redis(redisUrl); // For subscribing
console.log(`Connecting to Redis at: ${redisUrl}`);
// Configure Redis client with connection options
const redisOptions = {
retryStrategy: (times: number) => {
// Retry with exponential backoff up to 30 seconds
const delay = Math.min(times * 100, 3000);
console.log(`Redis connection attempt ${times} failed. Retrying in ${delay}ms...`);
return delay;
},
maxRetriesPerRequest: 5,
enableReadyCheck: true,
connectTimeout: 10000,
};
export const redis = new Redis(redisUrl, redisOptions);
export const redisPublisher = new Redis(redisUrl, redisOptions); // For publishing
export const redisSubscriber = new Redis(redisUrl, redisOptions); // For subscribing
// Log connection events
redis.on('connect', () => console.log('Redis client connected'));
redis.on('error', (err) => console.error('Redis client error:', err));
redis.on('ready', () => console.log('Redis client ready'));
redis.on('reconnecting', () => console.log('Redis client reconnecting...'));