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

Make file and dir server more efficient #29

Merged
merged 1 commit into from
Jan 9, 2025
Merged
Show file tree
Hide file tree
Changes from all 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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/build/
/_corral/
/_repos/
/lock.json
62 changes: 46 additions & 16 deletions jennet/fileserver.pony
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
use "files"
use "http_server"
use "valbytes"
use "debug"

use @pony_os_errno[I32]()

class _FileServer is RequestHandler
let _filepath: FilePath
Expand All @@ -10,18 +13,13 @@ class _FileServer is RequestHandler

fun val apply(ctx: Context): Context iso^ =>
try
var bs = ByteArrays
with file = OpenFile(_filepath) as File do
for line in file.lines() do
bs = bs + consume line
end
end
let data = _ReadFile(_filepath)?
ctx.respond(
StatusResponse(
StatusOK,
[("Content-Length", bs.size().string())]
[("Content-Length", data.size().string())]
),
bs
consume data
)
else
ctx.respond(StatusResponse(StatusNotFound))
Expand All @@ -37,20 +35,52 @@ class _DirServer is RequestHandler
fun val apply(ctx: Context): Context iso^ =>
let filepath = ctx.param("filepath")
try
var bs = ByteArrays
with file = OpenFile(_dir.join(filepath)?) as File do
for line in file.lines() do
bs = bs + consume line
end
end
let data = _ReadFile(_dir.join(filepath)?)?
ctx.respond(
StatusResponse(
StatusOK,
[("Content-Length", bs.size().string())]
[("Content-Length", data.size().string())]
),
bs
consume data
)
else
ctx.respond(StatusResponse(StatusNotFound))
end
consume ctx

primitive _ReadFile
"""
Read a whole file into an `Array[U8] iso^` doing multiple calls to read in a loop.

This is not optimally friendly to the whole runtime as it is hogging a scheduler thread doing blocking system calls.
"""
fun apply(path: FilePath): ByteArrays ? =>
Debug("Reading file " + path.path + " ...")
with file = OpenFile(path) as File do
file.clear_errno()
let file_size = file.size()

if file_size == -1 then
let err_str = match file.errno()
| FileError => "ERROR"
| FilePermissionDenied => "Permission denied"
| FileBadFileNumber => "Bad file number"
| FileEOF => "EOF"
| FileOK => "OK"
| FileExists => "EXISTS"
end
Debug("ERROR: " + @pony_os_errno().string() + " " + err_str)
error
end
Debug("file_size == " + if file_size == -1 then "-1" else file_size.string() end)
var bs = ByteArrays
var bytes_read = USize(0)
while bytes_read < file_size do
Debug("Reading " + (file_size - bytes_read).string() + " bytes from " + path.path)
let data = file.read(file_size - bytes_read)
bytes_read = bytes_read + data.size()
bs = bs + consume data
end
bs
end

4 changes: 2 additions & 2 deletions jennet/jennet.pony
Original file line number Diff line number Diff line change
Expand Up @@ -97,15 +97,15 @@ class iso Jennet
Serve static file located at the relative filepath when GET requests are
received for the given path.
"""
let caps = recover val FileCaps + FileRead + FileStat end
let caps = recover val FileCaps + FileRead + FileStat + FileSeek end
_add_route("GET", path, _FileServer(FilePath(auth, filepath, caps)), [])

fun ref serve_dir(auth: FileAuth, path: String, dir: String) =>
"""
Serve all files in dir using the incomming url path suffix denoted by
`*filepath` in the given path.
"""
let caps = recover val FileCaps + FileRead + FileStat + FileLookup end
let caps = recover val FileCaps + FileRead + FileStat + FileLookup + FileSeek end
_add_route("GET", path, _DirServer(FilePath(auth, dir, caps)), [])

fun ref not_found(handler: RequestHandler) =>
Expand Down
Loading