Passed
Push — main ( 74e679...90c63f )
by Julia
01:01 queued 20s
created

server/src/utils/clientManager.js   A

Complexity

Total Complexity 12
Complexity/F 1

Size

Lines of Code 78
Function Count 12

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
wmc 12
eloc 21
mnd 0
bc 0
fnc 12
dl 0
loc 78
rs 10
bpm 0
cpm 1
noi 0
c 0
b 0
f 0
1
import express from "express";
2
3
const CACHE_LIFETIME = 30 * 1000; // 30 seconds in milliseconds
4
5
/**
6
 * Manages client and bike connections with caching.
7
 */
8
const clientManager = {
9
    /** @type {Array<express.Response>} */
10
    clients: [],
11
12
    /** 
13
     * @type {Object<string, {data: any, res: express.Response | null, timestamp: number | null}>} 
14
     */
15
    cachedBikeData: {},
16
17
    /**
18
     * Adds a new client to the clients array.
19
     * @param {express.Response} client - The client to add.
20
     */
21
    addClient(client) {
22
        this.clients.push(client);
23
    },
24
25
    /**
26
     * Removes a client from the clients array.
27
     * @param {express.Response} client - The client to remove.
28
     */
29
    removeClient(client) {
30
        this.clients = this.clients.filter(c => c !== client);
31
    },
32
33
    /**
34
     * Initializes a new bike entry in the cache.
35
     * @param {Number} bikeId - The bike ID.
36
     * @param {express.Response} res - The bike connection response to add.
37
     */
38
    addBike(bikeId, res) {
39
        this.cachedBikeData[bikeId] = {
40
            res: res,
41
            data: null,
42
            timestamp: null
43
        };
44
    },
45
46
    /**
47
     * Removes a bike's res key (and value) from the cache object
48
     * @param {Number} bikeId - Id of the bike for which to set res to null
49
     */
50
    removeBike(bikeId) {
51
        this.cachedBikeData[bikeId].res = null
52
    },
53
54
    /**
55
     * Updates bike data in the cache and writes to database if necessary.
56
     * @param {Number} bikeId - The bike ID.
57
     * @param {any} dbData - Data to update database with.
58
     * @param {any} cachedData - Data to cache.
59
     * @param {Function} updateBike - Function to write data to the database.
60
     */
61
    async updateBikeData(bikeId, cachedData, dbData, updateBike) {
62
        const cacheEntry = this.cachedBikeData[bikeId];
63
64
        // Kolla om det finns en timestamp eller om cachen har gått ut
65
        const isCacheExpired = !cacheEntry.timestamp || (Date.now() - cacheEntry.timestamp > CACHE_LIFETIME);
66
67
        if (isCacheExpired) {
68
            // Om cachen är utgången eller inte finns --> uppdatera databasen
69
            await updateBike(
70
                dbData.id,
71
                dbData.status,
72
                dbData.charge,
73
                dbData.coords
74
            );
75
76
            // Uppdatera cachen med ny data och tidsstämpel
77
            this.cachedBikeData[bikeId] = {
78
                ...cacheEntry,
79
                data: cachedData,
80
                timestamp: Date.now()
81
            };
82
        } else {
83
            // Annars uppdatera endast cachad data
84
            this.cachedBikeData[bikeId].data = cachedData;
85
        }
86
    },
87
88
    /**
89
     * Broadcasts a message to all clients.
90
     * @param {Object} message - The message to broadcast.
91
     */
92
    broadcastToClients(message) {
93
        this.clients.forEach(client => client.write(`data: ${JSON.stringify(message)}\n\n`));
94
    },
95
96
97
    /**
98
     * Broadcasts a message to a specific bike.
99
     * @param {Number} bikeId - The ID of the bike to which the message should be broadcast.
100
     * @param {Object} message - The message to broadcast.
101
     */
102
    broadcastToBike(bikeId, message) {
103
        const bike = this.cachedBikeData[bikeId];
104
        
105
        if (bike && bike.res) {
106
            bike.res.write(`data: ${JSON.stringify(message)}\n\n`);
107
        }
108
    }
109
};
110
111
export default clientManager;
112