|
| 1 | +import net.http |
| 2 | +import sync.pool |
| 3 | +import time |
| 4 | +import vibe |
| 5 | +import cli |
| 6 | +import os |
| 7 | + |
| 8 | +pub struct GetResult { |
| 9 | + error_kind ?GetError |
| 10 | +} |
| 11 | + |
| 12 | +enum GetError { |
| 13 | + request_err |
| 14 | + status_err |
| 15 | +} |
| 16 | + |
| 17 | +fn std_request(mut pp pool.PoolProcessor, idx int, wid int) &GetResult { |
| 18 | + url := pp.get_item[string](idx) |
| 19 | + |
| 20 | + start := time.new_stopwatch() |
| 21 | + defer { println(' ${url}: ${start.elapsed()}') } |
| 22 | + |
| 23 | + mut req := http.Request{ |
| 24 | + url: 'https://${url}' |
| 25 | + method: .get |
| 26 | + } |
| 27 | + req.add_header(.user_agent, 'net-vibe-perf-test/0.0.1') |
| 28 | + |
| 29 | + resp := req.do() or { |
| 30 | + eprintln(' Failed to get: "${url}": ${err}') |
| 31 | + return &GetResult{.request_err} |
| 32 | + } |
| 33 | + if resp.status_code != 200 { |
| 34 | + eprintln(' Failed to get success response: "${resp.status}"') |
| 35 | + return &GetResult{.status_err} |
| 36 | + } |
| 37 | + |
| 38 | + // println(' Response content length: ${resp.body.len}') |
| 39 | + |
| 40 | + return &GetResult{} |
| 41 | +} |
| 42 | + |
| 43 | +fn vibe_request(mut pp pool.PoolProcessor, idx int, wid int) &GetResult { |
| 44 | + url := pp.get_item[string](idx) |
| 45 | + |
| 46 | + start := time.new_stopwatch() |
| 47 | + defer { println(' ${url}: ${start.elapsed()}') } |
| 48 | + |
| 49 | + mut req := vibe.Request{ |
| 50 | + headers: { |
| 51 | + .user_agent: 'net-vibe-perf-test/0.0.1' |
| 52 | + } |
| 53 | + } |
| 54 | + |
| 55 | + resp := req.get('https://${url}') or { |
| 56 | + eprintln(' Failed to get: "${url}": ${err}') |
| 57 | + return &GetResult{.request_err} |
| 58 | + } |
| 59 | + if resp.status != 200 { |
| 60 | + eprintln(' Failed to get success response: "${resp.status}"') |
| 61 | + return &GetResult{.status_err} |
| 62 | + } |
| 63 | + // println(' Response content length: ${resp.body.len}') |
| 64 | + |
| 65 | + return &GetResult{} |
| 66 | +} |
| 67 | + |
| 68 | +fn prep_urls(single_host bool, request_num int) ![]string { |
| 69 | + return if single_host { |
| 70 | + base := 'google.com/search?q=' |
| 71 | + []string{len: request_num, init: base + index.str()} |
| 72 | + } else { |
| 73 | + urls := 'https://gist.githubusercontent.com/ttytm/b2c6e348dac6b3f0ffa150639ad94211/raw/0823f71f18d5567d231dabbafe4ad22d006f0e61/100-popular-urls.txt' |
| 74 | + resp := http.get(urls)! |
| 75 | + resp.body.split_into_lines()[..request_num] |
| 76 | + } |
| 77 | +} |
| 78 | + |
| 79 | +fn main() { |
| 80 | + mut app := cli.Command{ |
| 81 | + name: 'net-vibe-perf-test' |
| 82 | + posix_mode: true |
| 83 | + execute: run |
| 84 | + flags: [ |
| 85 | + cli.Flag{ |
| 86 | + name: 'request-num' |
| 87 | + flag: .int |
| 88 | + abbrev: 'r' |
| 89 | + default_value: ['100'] // Currently the maximium number is capped by the number of prepared urls. |
| 90 | + }, |
| 91 | + cli.Flag{ |
| 92 | + name: 'single-host' |
| 93 | + flag: .bool |
| 94 | + abbrev: 's' |
| 95 | + }, |
| 96 | + cli.Flag{ |
| 97 | + name: 'use-vibe' |
| 98 | + flag: .bool |
| 99 | + }, |
| 100 | + ] |
| 101 | + } |
| 102 | + app.parse(os.args) |
| 103 | +} |
| 104 | + |
| 105 | +fn run(cmd cli.Command) ! { |
| 106 | + single_host := cmd.flags.get_bool('single-host')! |
| 107 | + use_vibe := cmd.flags.get_bool('use-vibe')! |
| 108 | + request_num := cmd.flags.get_int('request-num')! |
| 109 | + |
| 110 | + mut urls := prep_urls(single_host, if request_num < 100 { request_num } else { 100 })! |
| 111 | + |
| 112 | + start := time.new_stopwatch() |
| 113 | + |
| 114 | + mut pp := pool.new_pool_processor( |
| 115 | + callback: if use_vibe { vibe_request } else { std_request } |
| 116 | + ) |
| 117 | + pp.work_on_items(urls) |
| 118 | + |
| 119 | + results := pp.get_results[GetResult]() |
| 120 | + mut request_errs, mut status_errs := 0, 0 |
| 121 | + for v in results { |
| 122 | + err_kind := v.error_kind or { continue } |
| 123 | + if err_kind == GetError.request_err { |
| 124 | + request_errs++ |
| 125 | + } else { |
| 126 | + status_errs++ |
| 127 | + } |
| 128 | + } |
| 129 | + |
| 130 | + mod := if use_vibe { 'vibe' } else { 'net.http' } |
| 131 | + host_details := if single_host { ', single host' } else { '' } |
| 132 | + res := ' |
| 133 | +┌–––––––––––––––––––––––––––––––––––––––––––––––––––––––––┐ |
| 134 | + Results for "${mod}"${host_details} |
| 135 | + ––––––––––––––––––––––––––––––––––––––––––––––––––––––––– |
| 136 | + Requests: ${results.len}, Request errors: ${request_errs}, Status errors: ${status_errs} |
| 137 | + Total time: ${start.elapsed()} |
| 138 | +└–––––––––––––––––––––––––––––––––––––––––––––––––––––––––┘ |
| 139 | +' |
| 140 | + println(res) |
| 141 | + if os.getenv('GITHUB_JOB') != '' { |
| 142 | + os.system('echo ``` >> \$GITHUB_STEP_SUMMARY') |
| 143 | + for l in res.trim_space().split_into_lines() { |
| 144 | + os.system("echo '${l}' >> \$GITHUB_STEP_SUMMARY") |
| 145 | + } |
| 146 | + os.system("echo '```' >> \$GITHUB_STEP_SUMMARY") |
| 147 | + } |
| 148 | +} |
0 commit comments