Skip to content
This repository has been archived by the owner on Dec 27, 2022. It is now read-only.

First pass at disk quotas #34

Open
wants to merge 7 commits into
base: master
Choose a base branch
from

Conversation

dariusk
Copy link

@dariusk dariusk commented Apr 2, 2019

This is an attempt to implement the diskQuota and diskUsage features in DEP-0003. This is a draft implementation, and my first homebase contribution, so I'm sure there is a lot of room for improvement and it could use an extra set of eyes. There are a bunch of console logs in here which won't be in the final version, as well, but are included for the sake of debugging during development.

Basic features follow.

Add a diskQuota variable to the config

There is now a diskQuota field in the config that accepts a quota in bytes. I couldn't find a library that parses "human" byte strings like "100MB" or "1GB" to a byte Number, and in fact that might be an antipattern so I'm just sticking to raw bytes. Since the users of homebase are sysadmins of some flavor, I think this should be okay.

Return diskQuota and diskUsage on GET account call

When you send GET /v1/accounts/account, you now get the quota and space used, per DEP-0003.

Rejects a new pinning request if accepting the request would put the user over quota

On a call to /v1/dats/add, the sparse statistics for the dat are downloaded. This tells us how big the full dat is, and we do the math based on the existing diskUsage and return a 403 error and message, User is over quota: requested dat is ${datSize} bytes, user has ${config.diskQuota - config.diskUsage} bytes remaining.

On downloading a chunk of a dat, check to see if we are over quota

On a 'download' event, if the chunk being downloaded would put us over quota, we stop downloading this particular dat.

We keep a running estimatedDiskUsage that is occasionally synced to the "real" diskUsage so we don't have to parse the entire directory tree every time a chunk is downloaded from an active dat. estimatedDiskUsage is synchronized to the real value every five minutes and on startup.

Re-allow all downloads if we go back under quota

When we check the real diskUsage every five minutes, if we are under quota, we restart all dats, which allows for downloads again. Currently this will restart all dats every five minutes while we're under quota. I'm not sure if this is a "free" operation for a dat that is currently already active. Maybe we should make activeDats available somehow and only restart dats that are not in that object?

@dariusk
Copy link
Author

dariusk commented Apr 2, 2019

Oh and I do plan to update the README as well but will save that for a time when the implementation is final.

Per DEP-0003, a "0" means "no quota". This ignores quotas when
`diskQuota` is set to 0.
Copy link
Member

@pfrazee pfrazee left a comment

Choose a reason for hiding this comment

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

Looks good just reading over it. I'd like to have some tests before merging.

lib/config.js Outdated Show resolved Hide resolved
lib/config.js Outdated Show resolved Hide resolved
dariusk added 4 commits April 17, 2019 12:28
When we're over quota there is no reason to stop serving chunks of a dat
out to people who request them. We simply need to stop incoming updates
to the dat, so what we do is leave the network and the re-join with
{download: false} passed as an option to the dat.
Per @pfrazee's code review, it makes more sense for this function to
live in `server.js`.
lib/server.js Outdated Show resolved Hide resolved
lib/server.js Show resolved Hide resolved
lib/server.js Outdated Show resolved Hide resolved
// update the disk space seems right
console.log(config.diskUsage, config.diskQuota, config.diskUsage/config.diskQuota)
if (config.diskUsage < config.diskQuota) {
config.dats.forEach(datCfg => dat.start(datCfg, config))
Copy link
Member

Choose a reason for hiding this comment

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

This isn't the correct usage of dat.start. See https://github.com/beakerbrowser/homebase/blob/master/lib/server.js#L141 -- the method returns a server instance which is supposed to be integrated into the top level express server.


// align our estimated disk usage with real disk usage every 5 minutes
updateDiskUsage(this)
setInterval(updateDiskUsage.bind(this), 1000*60*5, this)
Copy link
Member

Choose a reason for hiding this comment

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

I'd recommend calling updateDiskUsage and setting up the interval from server.js

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants