feat: implement Pluggable Abstraction Layer for Data Retrieval (PALDRA) - #19
All checks were successful
All checks were successful
- Create ArrRetriever abstract base class defining pluggable interface - Implement PollingSonarrRetriever and PollingRadarrRetriever with HTTP polling - Add ArrRetrieverRegistry for managing retriever instances - Refactor poller.js to use retriever registry instead of direct Axios calls - Update historyFetcher.js to use retriever registry - Preserve all cache keys, TTLs, timing logs, SSE broadcasts, error handling - Enable future webhook listeners without touching poller logic
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
const axios = require('axios');
|
||||
const cache = require('./cache');
|
||||
const { initializeClients, getAllDownloads, getDownloadsByClientType } = require('./downloadClients');
|
||||
const { initializeRetrievers, getTagsByType, getQueuesByType, getHistoryByType } = require('./arrRetrievers');
|
||||
const {
|
||||
getSonarrInstances,
|
||||
getRadarrInstances
|
||||
@@ -38,8 +39,9 @@ async function pollAllServices() {
|
||||
const start = Date.now();
|
||||
|
||||
try {
|
||||
// Ensure download clients are initialized
|
||||
// Ensure download clients and *arr retrievers are initialized
|
||||
await initializeClients();
|
||||
await initializeRetrievers();
|
||||
|
||||
const sonarrInstances = getSonarrInstances();
|
||||
const radarrInstances = getRadarrInstances();
|
||||
@@ -50,58 +52,30 @@ async function pollAllServices() {
|
||||
const downloadsByType = await getDownloadsByClientType();
|
||||
return downloadsByType;
|
||||
}),
|
||||
timed('Sonarr Tags', () => Promise.all(sonarrInstances.map(inst =>
|
||||
axios.get(`${inst.url}/api/v3/tag`, {
|
||||
headers: { 'X-Api-Key': inst.apiKey }
|
||||
}).then(res => ({ instance: inst.id, data: res.data })).catch(err => {
|
||||
console.error(`[Poller] Sonarr ${inst.id} tags error:`, err.message);
|
||||
return { instance: inst.id, data: [] };
|
||||
})
|
||||
))),
|
||||
timed('Sonarr Queue', () => Promise.all(sonarrInstances.map(inst =>
|
||||
axios.get(`${inst.url}/api/v3/queue`, {
|
||||
headers: { 'X-Api-Key': inst.apiKey },
|
||||
params: { includeSeries: true, includeEpisode: true }
|
||||
}).then(res => ({ instance: inst.id, data: res.data })).catch(err => {
|
||||
console.error(`[Poller] Sonarr ${inst.id} queue error:`, err.message);
|
||||
return { instance: inst.id, data: { records: [] } };
|
||||
})
|
||||
))),
|
||||
timed('Sonarr History', () => Promise.all(sonarrInstances.map(inst =>
|
||||
axios.get(`${inst.url}/api/v3/history`, {
|
||||
headers: { 'X-Api-Key': inst.apiKey },
|
||||
params: { pageSize: 10, includeEpisode: true }
|
||||
}).then(res => ({ instance: inst.id, data: res.data })).catch(err => {
|
||||
console.error(`[Poller] Sonarr ${inst.id} history error:`, err.message);
|
||||
return { instance: inst.id, data: { records: [] } };
|
||||
})
|
||||
))),
|
||||
timed('Radarr Queue', () => Promise.all(radarrInstances.map(inst =>
|
||||
axios.get(`${inst.url}/api/v3/queue`, {
|
||||
headers: { 'X-Api-Key': inst.apiKey },
|
||||
params: { includeMovie: true }
|
||||
}).then(res => ({ instance: inst.id, data: res.data })).catch(err => {
|
||||
console.error(`[Poller] Radarr ${inst.id} queue error:`, err.message);
|
||||
return { instance: inst.id, data: { records: [] } };
|
||||
})
|
||||
))),
|
||||
timed('Radarr History', () => Promise.all(radarrInstances.map(inst =>
|
||||
axios.get(`${inst.url}/api/v3/history`, {
|
||||
headers: { 'X-Api-Key': inst.apiKey },
|
||||
params: { pageSize: 10 }
|
||||
}).then(res => ({ instance: inst.id, data: res.data })).catch(err => {
|
||||
console.error(`[Poller] Radarr ${inst.id} history error:`, err.message);
|
||||
return { instance: inst.id, data: { records: [] } };
|
||||
})
|
||||
))),
|
||||
timed('Radarr Tags', () => Promise.all(radarrInstances.map(inst =>
|
||||
axios.get(`${inst.url}/api/v3/tag`, {
|
||||
headers: { 'X-Api-Key': inst.apiKey }
|
||||
}).then(res => ({ instance: inst.id, data: res.data })).catch(err => {
|
||||
console.error(`[Poller] Radarr ${inst.id} tags error:`, err.message);
|
||||
return { instance: inst.id, data: [] };
|
||||
})
|
||||
))),
|
||||
timed('Sonarr Tags', async () => {
|
||||
const tagsByType = await getTagsByType();
|
||||
return tagsByType.sonarr || [];
|
||||
}),
|
||||
timed('Sonarr Queue', async () => {
|
||||
const queuesByType = await getQueuesByType();
|
||||
return queuesByType.sonarr || [];
|
||||
}),
|
||||
timed('Sonarr History', async () => {
|
||||
const historyByType = await getHistoryByType({ pageSize: 10 });
|
||||
return historyByType.sonarr || [];
|
||||
}),
|
||||
timed('Radarr Queue', async () => {
|
||||
const queuesByType = await getQueuesByType();
|
||||
return queuesByType.radarr || [];
|
||||
}),
|
||||
timed('Radarr History', async () => {
|
||||
const historyByType = await getHistoryByType({ pageSize: 10 });
|
||||
return historyByType.radarr || [];
|
||||
}),
|
||||
timed('Radarr Tags', async () => {
|
||||
const tagsByType = await getTagsByType();
|
||||
return tagsByType.radarr || [];
|
||||
}),
|
||||
]);
|
||||
|
||||
const [
|
||||
|
||||
Reference in New Issue
Block a user