Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: egress tracker middleware #120

Merged
merged 2 commits into from
Oct 30, 2024
Merged

feat: egress tracker middleware #120

merged 2 commits into from
Oct 30, 2024

Conversation

fforbeck
Copy link
Member

@fforbeck fforbeck commented Oct 28, 2024

Egress Tracker Middleware

Summary:
This PR introduces an egress tracking middleware for the Freeway project, enabling accurate measurement and recording of egress data for served content. The middleware tracks the bytes sent in each response body and logs them with the accounting service tied to each content ID (CID).

Key Changes:

  • Egress Middleware (withEgressHandler):

    • Wraps response handlers to track and count bytes sent to the client.
    • Controlled by the FF_EGRESS_TRACKER_ENABLED feature flag, enabling or disabling egress tracking as needed. It is disabled by default.
  • Accounting Service Integration:

    • Logs egress data with the accounting service, using either an ACCOUNTING_SERVICE from the context or a new instance based on the ACCOUNTING_SERVICE_URL environment variable.
    • Egress data is linked to the CID of the served content, ensuring precise tracking. (The actual accounting service implementation, integrating w3up-client for the new usage/record capability, will follow in a separate PR.)
  • Efficient Byte Counting via TransformStream:

    • Utilizes a TransformStream (createEgressPassThroughStream) to passively count bytes in the response body without altering content.
    • On stream completion, the flush method records total egress to the accounting service using ctx.waitUntil() for non-blocking calls.

Error Handling:

  • Logs errors encountered during data streaming and halts byte counting without interrupting the original response chain. This ensures resilience even in cases of partial or interrupted streams.

Testing:

  • Added thorough tests to validate egress recording across scenarios, including complete responses, interrupted streams, and error cases.

Next Steps:

  • Integration tests for verifying egress tracking accuracy and accounting service interactions in various streaming conditions (planned for a future PR).
  • w3up-client integration to execute the new usage/record capability in subsequent development.

@fforbeck fforbeck force-pushed the feat/egress-tracking branch 3 times, most recently from f21680e to b99bf75 Compare October 29, 2024 14:43
write: (block) => { blocks.push(block) }
}))

// expect(blocks[0].bytes).to.deep.equal(carBytes) - FIXME (fforbeck): how to get the correct byte count?
Copy link
Member Author

Choose a reason for hiding this comment

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

Still need to figure out how to check the byte count of the returned CAR file.

Copy link
Member Author

Choose a reason for hiding this comment

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

@Peeja / @hannahhoward, any advice on comparing the total bytes of the returned CAR file with expectedTotalBytes? I suspect I'm not converting the file correctly. Any tips would be helpful!

@fforbeck fforbeck marked this pull request as ready for review October 29, 2024 15:42
@fforbeck fforbeck changed the title feat: egress tracking feat: egress tracker middleware Oct 29, 2024
Peeja
Peeja previously requested changes Oct 29, 2024
Copy link
Member

@Peeja Peeja left a comment

Choose a reason for hiding this comment

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

Looking good! Some suggestions:

test/fixtures/worker-fixture.js Outdated Show resolved Hide resolved
src/handlers/egress-tracker.js Outdated Show resolved Hide resolved
src/handlers/egress-tracker.js Outdated Show resolved Hide resolved
src/handlers/egress-tracker.js Outdated Show resolved Hide resolved
src/handlers/egress-tracker.js Outdated Show resolved Hide resolved
src/handlers/egress-tracker.js Outdated Show resolved Hide resolved
src/bindings.d.ts Show resolved Hide resolved
src/handlers/rate-limiter.js Outdated Show resolved Hide resolved
test/unit/middlewares/egress-tracker.spec.js Outdated Show resolved Hide resolved
test/unit/middlewares/egress-tracker.spec.js Outdated Show resolved Hide resolved
Copy link
Member

@hannahhoward hannahhoward left a comment

Choose a reason for hiding this comment

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

LGTM but agree with @Peeja 's comments

src/handlers/egress-tracker.js Outdated Show resolved Hide resolved
src/handlers/egress-tracker.js Outdated Show resolved Hide resolved
@fforbeck fforbeck force-pushed the feat/egress-tracking branch 2 times, most recently from 6bad2ac to 67cb972 Compare October 29, 2024 19:45
@fforbeck fforbeck dismissed Peeja’s stale review October 30, 2024 12:59

waiting for another review.

Copy link
Member

@Peeja Peeja left a comment

Choose a reason for hiding this comment

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

Woohoo! Looking even better!

I dug into the tests a bit more. My main concern is that they're a bit hard to follow when you don't have all the context loaded in your brain. Hopefully these suggestions improve that?

src/middleware/withEgressTracker.js Show resolved Hide resolved
src/middleware/withEgressTracker.js Show resolved Hide resolved
expect(accountingRecordMethodStub.args[0][1], 'second argument should be the total bytes').to.equal(totalBytes)
})

it('should record egress bytes for a CAR file request', async () => {
Copy link
Member

Choose a reason for hiding this comment

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

question: Is this testing anything in particular about withEgressTracker? It seems to me like it's just the same as any wrapped response.

suggestion: If I'm not missing something here, I'd remove this test and the setup complexity that comes with it.

@fforbeck
Copy link
Member Author

@Peeja - thanks for the review! Since these suggestions are test-related and don’t seem to be blockers, would you be open to merging this now and handling the remaining refactor in PR #122? (which will affect the egress handler and accounting service anyway).

Copy link
Member

@Peeja Peeja left a comment

Choose a reason for hiding this comment

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

Approving so test changes can happen in #123

@fforbeck fforbeck merged commit 847829b into main Oct 30, 2024
1 check passed
@fforbeck fforbeck deleted the feat/egress-tracking branch October 30, 2024 15:39
hannahhoward pushed a commit that referenced this pull request Nov 9, 2024
🤖 I have created a release *beep* *boop*
---


##
[2.21.0](v2.20.2...v2.21.0)
(2024-11-06)


### Features

* **blob-fetcher:** use updated blob fetcher
([#124](#124))
([90bb605](90bb605))
* egress tracker middleware
([#120](#120))
([847829b](847829b))
* rate limiter + unit tests + readme
([#115](#115))
([7bc4c6d](7bc4c6d))


### Bug Fixes

* **test:** enable nodejs compat for miniflare
([#127](#127))
([0165521](0165521))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants