Skip to content

Commit

Permalink
update to add redisUtils and update session management to use redisUtils
Browse files Browse the repository at this point in the history
  • Loading branch information
bhnuka committed Oct 18, 2024
1 parent 4987f10 commit 75ccf59
Show file tree
Hide file tree
Showing 4 changed files with 155 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import SessionObj from '../models/SessionObj';
import TimeOutObj from '../models/TimeOutObj';

class RunnerController {
// Example usage: Start a session with a timeout
// Start a new session with a timeout for matching
async startSession(req: Request, res: Response): Promise<void> {
const { sessionId, userId1, timeoutDuration } = req.body;

Expand All @@ -18,25 +18,60 @@ class RunnerController {
res.status(200).json({ message: 'Session started and timeout set.' });
}

// Example usage: Check for session expiration
async checkSessionExpiration(req: Request, res: Response): Promise<void> {
const { sessionId } = req.params;
// Add a second user to the session and update the session status
async addUserToSession(req: Request, res: Response): Promise<void> {
const { sessionId, userId2 } = req.body;

// Find session
const session = await SessionObj.find(sessionId);
if (!session) {
res.status(404).json({ message: 'Session not found.' });
return;
}

// Check if the session has expired
const isExpired = await TimeOutObj.isExpired(sessionId);
if (isExpired) {
res.status(400).json({ message: 'Session expired.' });
} else {
res.status(200).json({ message: 'Session is still active.' });
return;
}

// Add second user to the session and update the status
await session.addUser(userId2);

// Cancel the timeout since we have a match
await TimeOutObj.cancelTimeout(sessionId);

res.status(200).json({ message: 'User added and session matched.' });
}

// Check the status of a session
async checkSessionStatus(req: Request, res: Response): Promise<void> {
const { sessionId } = req.params;

// Find session
const session = await SessionObj.find(sessionId);
if (!session) {
res.status(404).json({ message: 'Session not found.' });
return;
}

// Use getters to access private properties
res.status(200).json({
sessionId: sessionId,
status: session.getStatus, // Access the status using the getter
userId1: session.getUserId1, // Access userId1 using the getter
userId2: session.getUserId2, // Access userId2 using the getter
});
}

// Example usage: Cancel session timeout
// Cancel a session timeout and delete the session
async cancelSession(req: Request, res: Response): Promise<void> {
const { sessionId } = req.body;

// Cancel the timeout and remove session from Redis
await TimeOutObj.cancelTimeout(sessionId);

res.status(200).json({ message: 'Session timeout cancelled.' });
}
}
Expand Down
22 changes: 17 additions & 5 deletions peerprep/backend/matching-service/src/models/SessionObj.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import connectRedis from '../../config/redis';
import redisUtils from '../utils/redisUtils';

class SessionObj {
private sessionId: string;
Expand All @@ -15,20 +15,31 @@ class SessionObj {
this.createdAt = new Date();
}

// Getters for private properties
get getStatus(): string {
return this.status;
}

get getUserId1(): string {
return this.userId1;
}

get getUserId2(): string | null {
return this.userId2;
}

async save(): Promise<void> {
const redisClient = await connectRedis(); // Connect to Redis
const sessionData = JSON.stringify({
userId1: this.userId1,
userId2: this.userId2,
status: this.status,
createdAt: this.createdAt.toISOString(),
});
await redisClient.set(this.sessionId, sessionData);
await redisUtils.set(this.sessionId, sessionData);
}

static async find(sessionId: string): Promise<SessionObj | null> {
const redisClient = await connectRedis(); // Connect to Redis
const sessionData = await redisClient.get(sessionId);
const sessionData = await redisUtils.get(sessionId);
if (!sessionData) {
return null;
}
Expand All @@ -55,3 +66,4 @@ class SessionObj {
}

export default SessionObj;

18 changes: 8 additions & 10 deletions peerprep/backend/matching-service/src/models/TimeOutObj.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import connectRedis from '../../config/redis';
import redisUtils from '../utils/redisUtils';

class TimeOutObj {
private sessionId: string;
Expand All @@ -9,25 +9,23 @@ class TimeOutObj {
this.timeoutDuration = timeoutDuration;
}

// Start the timeout for the session
// Start the timeout for the session, store with an expiration in Redis
async startTimeout(): Promise<void> {
const redisClient = await connectRedis(); // Establish Redis connection
await redisClient.setex(this.sessionId, this.timeoutDuration, 'waiting'); // 'waiting' status during timeout
await redisUtils.set(this.sessionId, 'waiting', this.timeoutDuration);
}

// Check if a session has expired (i.e., if it's no longer in Redis)
// Check if a session has expired by checking if the session exists in Redis
static async isExpired(sessionId: string): Promise<boolean> {
const redisClient = await connectRedis(); // Establish Redis connection
const status = await redisClient.get(sessionId);
return status === null; // Return true if session data no longer exists
const status = await redisUtils.get(sessionId);
return status === null; // If the key doesn't exist, it has expired
}

// Cancel the timeout (delete the session entry from Redis)
static async cancelTimeout(sessionId: string): Promise<void> {
const redisClient = await connectRedis(); // Establish Redis connection
await redisClient.del(sessionId); // Remove session from Redis
await redisUtils.del(sessionId);
}
}

export default TimeOutObj;


88 changes: 88 additions & 0 deletions peerprep/backend/matching-service/src/utils/redisUtils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import connectRedis from '../../config/redis';

const redisUtils = {
/**
* Sets a key-value pair in Redis with an optional expiration time (in seconds).
* @param key - The key to store the data.
* @param value - The value to be stored.
* @param expirationInSeconds - Optional expiration time for the key.
*/
async set(key: string, value: string, expirationInSeconds?: number): Promise<void> {
const redisClient = await connectRedis();

if (expirationInSeconds) {
await redisClient.setex(key, expirationInSeconds, value);
} else {
await redisClient.set(key, value);
}
},

/**
* Retrieves a value by key from Redis.
* @param key - The key for the data to retrieve.
* @returns - The stored value or null if the key does not exist.
*/
async get(key: string): Promise<string | null> {
const redisClient = await connectRedis();
const value = await redisClient.get(key);
return value;
},

/**
* Deletes a key from Redis.
* @param key - The key to delete.
* @returns - The number of keys that were removed.
*/
async del(key: string): Promise<number> {
const redisClient = await connectRedis();
const result = await redisClient.del(key);
return result;
},

/**
* Checks if a key exists in Redis.
* @param key - The key to check.
* @returns - 1 if the key exists, 0 if the key does not exist.
*/
async exists(key: string): Promise<number> {
const redisClient = await connectRedis();
const exists = await redisClient.exists(key);
return exists;
},

/**
* Sets a key-value pair in Redis only if the key does not already exist.
* @param key - The key to store the data.
* @param value - The value to store.
* @returns - True if the key was set, false if it already exists.
*/
async setnx(key: string, value: string): Promise<boolean> {
const redisClient = await connectRedis();
const result = await redisClient.setnx(key, value);
return result === 1; // Redis returns 1 if the key was set, 0 if it was not.
},

/**
* Increments a value stored at a key.
* @param key - The key whose value will be incremented.
* @returns - The new value after incrementing.
*/
async incr(key: string): Promise<number> {
const redisClient = await connectRedis();
const newValue = await redisClient.incr(key);
return newValue;
},

/**
* Decrements a value stored at a key.
* @param key - The key whose value will be decremented.
* @returns - The new value after decrementing.
*/
async decr(key: string): Promise<number> {
const redisClient = await connectRedis();
const newValue = await redisClient.decr(key);
return newValue;
}
};

export default redisUtils;

0 comments on commit 75ccf59

Please sign in to comment.