vweb: cleanup run_at

This commit is contained in:
Delyan Angelov 2023-10-20 04:06:37 +03:00
parent 93ff40aeed
commit 2766c8b4be
No known key found for this signature in database
GPG Key ID: 66886C0F12D595ED
2 changed files with 32 additions and 28 deletions

View File

@ -11,17 +11,15 @@ fn (mut c Checker) fn_decl(mut node ast.FnDecl) {
eprintln('>>> post processing node.name: ${node.name:-30} | ${node.generic_names} <=> ${c.table.cur_concrete_types}')
}
}
// notice vweb route methods (non-generic method)
if node.generic_names.len > 0 {
// record the vweb route methods (public non-generic methods):
if node.generic_names.len > 0 && node.is_pub {
typ_vweb_result := c.table.find_type_idx('vweb.Result')
if node.return_type == typ_vweb_result {
rec_sym := c.table.sym(node.receiver.typ)
if rec_sym.kind == .struct_ {
if _ := c.table.find_field_with_embeds(rec_sym, 'Context') {
// there is no point in the message here, for methods that are not public; since they will not be available as routes anyway
if node.is_pub {
c.note('generic method routes of vweb will be skipped', node.pos)
}
c.note('generic method routes of vweb will be skipped', node.pos)
}
}
}

View File

@ -517,34 +517,15 @@ pub fn run_at[T](global_app &T, params RunParams) ! {
return error('invalid nr_workers `${params.nr_workers}`, it should be above 0')
}
mut l := net.listen_tcp(params.family, '${params.host}:${params.port}') or {
listen_address := '${params.host}:${params.port}'
// eprintln('>> vweb listen_address: `${listen_address}` | params.family: ${params.family}')
mut l := net.listen_tcp(params.family, listen_address) or {
ecode := err.code()
return error('failed to listen ${ecode} ${err}')
}
routes := generate_routes(global_app)!
// check duplicate routes in controllers
mut controllers_sorted := []&ControllerPath{}
$if T is ControllerInterface {
mut paths := []string{}
controllers_sorted = global_app.controllers.clone()
controllers_sorted.sort(a.path.len > b.path.len)
for controller in controllers_sorted {
if controller.host == '' {
if controller.path in paths {
return error('conflicting paths: duplicate controller handling the route "${controller.path}"')
}
paths << controller.path
}
}
for method_name, route in routes {
for controller_path in paths {
if route.path.starts_with(controller_path) {
return error('conflicting paths: method "${method_name}" with route "${route.path}" should be handled by the Controller of path "${controller_path}"')
}
}
}
}
controllers_sorted := check_duplicate_routes_in_controllers[T](routes)!
host := if params.host == '' { 'localhost' } else { params.host }
if params.show_startup_message {
@ -578,6 +559,31 @@ pub fn run_at[T](global_app &T, params RunParams) ! {
}
}
fn check_duplicate_routes_in_controllers[T](routes map[string]Route) ![]&ControllerPath {
mut controllers_sorted := []&ControllerPath{}
$if T is ControllerInterface {
mut paths := []string{}
controllers_sorted = global_app.controllers.clone()
controllers_sorted.sort(a.path.len > b.path.len)
for controller in controllers_sorted {
if controller.host == '' {
if controller.path in paths {
return error('conflicting paths: duplicate controller handling the route "${controller.path}"')
}
paths << controller.path
}
}
for method_name, route in routes {
for controller_path in paths {
if route.path.starts_with(controller_path) {
return error('conflicting paths: method "${method_name}" with route "${route.path}" should be handled by the Controller of path "${controller_path}"')
}
}
}
}
return controllers_sorted
}
fn new_request_app[T](global_app &T, ctx Context, tid int) &T {
// Create a new app object for each connection, copy global data like db connections
mut request_app := &T{}