added documentation
This commit is contained in:
@@ -16,3 +16,26 @@
|
|||||||
- ~fetch requested files from mirror~
|
- ~fetch requested files from mirror~
|
||||||
- ~DB sync from mirror~
|
- ~DB sync from mirror~
|
||||||
- ~Config file and import~
|
- ~Config file and import~
|
||||||
|
|
||||||
|
Looking at what you've built and what's left on your TODO, here's how I'd think about the "done" line for a capstone:
|
||||||
|
|
||||||
|
**What you already have that's impressive:**
|
||||||
|
- Real concurrent systems work — singleflight, atomic ops, mutex
|
||||||
|
- Custom HTTP transport with timeout tuning
|
||||||
|
- Atomic file writes with the tmp-then-rename pattern
|
||||||
|
- Meaningful test suite with httptest, not just trivial unit tests
|
||||||
|
- Clean dependency injection, thoughtful package boundaries
|
||||||
|
- Config validation with proper error wrapping
|
||||||
|
|
||||||
|
**What would make it a complete capstone story:**
|
||||||
|
- The streaming solution for large packages — this is your most interesting unsolved technical problem and directly demonstrates you understand the HTTP layer
|
||||||
|
- At least one more meaningful feature working end-to-end, either the refresh scheduling via systemd timer or the prefetch-on-refresh logic
|
||||||
|
- Actually deployed and serving your home network — "running in production" is a strong closer
|
||||||
|
|
||||||
|
**What I'd leave out of the capstone scope:**
|
||||||
|
- The AUR builder — that's a whole second project honestly
|
||||||
|
- Chi middleware — nice but not substantive enough to matter
|
||||||
|
|
||||||
|
The through-line you want to be able to tell is: *I built a caching reverse proxy from scratch in Go, handling concurrency, filesystem atomicity, and HTTP semantics correctly, and deployed it on real hardware.* You're close to being able to say that. The streaming piece and a working deployment are the remaining gaps.
|
||||||
|
|
||||||
|
How far out is the capstone deadline?
|
||||||
|
|||||||
Vendored
+5
@@ -78,8 +78,11 @@ func (e *UpstreamError) Error() string {
|
|||||||
func (c *Cache) fetch(pkgName string) error {
|
func (c *Cache) fetch(pkgName string) error {
|
||||||
// pkgName is relative to the localRoot
|
// pkgName is relative to the localRoot
|
||||||
// ie pkgName includes /{repo}/os/{arch}/ and the actual name linux-x.x.x.pkg.tar.zst
|
// ie pkgName includes /{repo}/os/{arch}/ and the actual name linux-x.x.x.pkg.tar.zst
|
||||||
|
|
||||||
tempPkgName := pkgName + ".tmp"
|
tempPkgName := pkgName + ".tmp"
|
||||||
tempPkgPath := filepath.Join(c.cfg.cacheRoot, tempPkgName) //full tmp write path
|
tempPkgPath := filepath.Join(c.cfg.cacheRoot, tempPkgName) //full tmp write path
|
||||||
|
|
||||||
|
// final file name and path
|
||||||
outPkg := filepath.Join(c.cfg.cacheRoot, pkgName)
|
outPkg := filepath.Join(c.cfg.cacheRoot, pkgName)
|
||||||
pkgURL := c.nextMirror() + pkgName
|
pkgURL := c.nextMirror() + pkgName
|
||||||
|
|
||||||
@@ -95,6 +98,7 @@ func (c *Cache) fetch(pkgName string) error {
|
|||||||
return &UpstreamError{StatusCode: resp.StatusCode}
|
return &UpstreamError{StatusCode: resp.StatusCode}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// use a tmp file for the initial fetch in case it fails
|
||||||
outFile, err := os.Create(tempPkgPath)
|
outFile, err := os.Create(tempPkgPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -107,6 +111,7 @@ func (c *Cache) fetch(pkgName string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// mv file to final location
|
||||||
if err := os.Rename(tempPkgPath, outPkg); err != nil {
|
if err := os.Rename(tempPkgPath, outPkg); err != nil {
|
||||||
os.Remove(tempPkgPath)
|
os.Remove(tempPkgPath)
|
||||||
return err
|
return err
|
||||||
|
|||||||
Reference in New Issue
Block a user