Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ Base URL: http://stats.filspark.com/

http://stats.filspark.com/participants/top-measurements?from=yesterday&to=yesterday

- `GET /participants/summary`

http://stats.filspark.com/participants/summary

- `GET /participant/:address/scheduled-rewards?address=<address>&from=<day>&to=<day>`

http://stats.filspark.com/participant/0x000000000000000000000000000000000000dEaD/scheduled-rewards
Expand Down
8 changes: 7 additions & 1 deletion stats/lib/platform-routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@ import {
fetchDailyRewardTransfers,
fetchTopEarningParticipants,
fetchParticipantsWithTopMeasurements,
fetchDailyStationMeasurementCounts
fetchDailyStationMeasurementCounts,
fetchParticipantsSummary
} from './platform-stats-fetchers.js'
import { json } from 'http-responders'

const createRespondWithFetchFn = (pathname, searchParams, res) => (pgPool, fetchFn) => {
return getStatsWithFilterAndCaching(
Expand Down Expand Up @@ -36,6 +38,10 @@ export const handlePlatformRoutes = async (req, res, pgPools) => {
await respond(pgPools.evaluate, fetchParticipantsWithTopMeasurements)
} else if (req.method === 'GET' && url === '/participants/top-earning') {
await respond(pgPools.stats, fetchTopEarningParticipants)
} else if (req.method === 'GET' && url === '/participants/summary') {
const summary = await fetchParticipantsSummary(pgPools.evaluate)
res.setHeader('cache-control', `public, max-age=${24 * 3600 /* one day */}`)
json(res, summary)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would you mind extracting these three lines into a new function? I would like to keep handlePlatformRoutes at a single level of abstraction - match request method+path and call the appropriate route handler.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have refactored dc18234 but don't know where to put it. I also don't see a good way to refactor a generic getStatsWithCaching function. Can you please advise in more detail how you envision this?

} else if (req.method === 'GET' && url === '/transfers/daily') {
await respond(pgPools.stats, fetchDailyRewardTransfers)
} else {
Expand Down
12 changes: 12 additions & 0 deletions stats/lib/platform-stats-fetchers.js
Original file line number Diff line number Diff line change
Expand Up @@ -104,3 +104,15 @@ export const fetchTopEarningParticipants = async (pgPool, filter) => {
`, [filter.from, filter.to])
return rows
}

/**
* @param {Queryable} pgPool
*/
export const fetchParticipantsSummary = async (pgPool) => {
const { rows } = await pgPool.query(`
SELECT COUNT(DISTINCT participant_id) FROM daily_participants
`)
return {
participant_count: Number(rows[0].count)
}
}
24 changes: 24 additions & 0 deletions stats/test/platform-routes.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { getPgPools } from '@filecoin-station/spark-stats-db'
import { assertResponseStatus, getPort } from './test-helpers.js'
import { createHandler } from '../lib/handler.js'
import { getLocalDayAsISOString, today, yesterday } from '../lib/request-helpers.js'
import { givenDailyParticipants } from '@filecoin-station/spark-stats-db/test-helpers.js'

const debug = createDebug('test')

Expand Down Expand Up @@ -338,6 +339,29 @@ describe('Platform Routes HTTP request handler', () => {
await assertResponseStatus(res, 400)
})
})

describe('GET /participants/summary', () => {
it('counts participants', async () => {
await givenDailyParticipants(
pgPools.evaluate,
'2000-01-01',
['0x1', '0x2', '0x3']
)

const res = await fetch(
new URL('/participants/summary', baseUrl), {
redirect: 'manual'
}
)
await assertResponseStatus(res, 200)
const summary = await res.json()
assert.deepStrictEqual(summary, { participant_count: 3 })
assert.strictEqual(
res.headers.get('cache-control'),
'public, max-age=86400'
)
})
})
})

const givenDailyMeasurementsSummary = async (pgPoolEvaluate, summaryData) => {
Expand Down