1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

vlib: improvements to the context module (#18318)

This commit is contained in:
Ulises Jeremias Cornejo Fandos 2023-06-04 13:12:52 -03:00 committed by GitHub
parent 0e106c9062
commit 02ea6028af
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 77 additions and 69 deletions

View File

@ -86,8 +86,8 @@ const (
'do_not_remove',
'cmd/tools/vdoc/html_tag_escape_test.v', /* can't locate local module: markdown */
'cmd/tools/vdoc/tests/vdoc_file_test.v', /* fails on Windows; order of output is not as expected */
'vlib/context/onecontext/onecontext_test.v',
'vlib/context/deadline_test.v' /* sometimes blocks */,
'vlib/context/onecontext/onecontext_test.v' /* backtrace_symbols is missing. */,
'vlib/db/mysql/mysql_orm_test.v' /* mysql not installed */,
'vlib/db/pg/pg_orm_test.v' /* pg not installed */,
]
@ -246,10 +246,6 @@ const (
]
skip_on_windows = [
'do_not_remove',
'vlib/context/cancel_test.v',
'vlib/context/deadline_test.v',
'vlib/context/empty_test.v',
'vlib/context/value_test.v',
'vlib/orm/orm_test.v',
'vlib/v/tests/orm_sub_struct_test.v',
'vlib/v/tests/orm_joined_tables_select_test.v',

View File

@ -62,7 +62,7 @@ fn main() {
}
mut background := context.background()
mut ctx, cancel := context.with_cancel(mut &background)
mut ctx, cancel := context.with_cancel(mut background)
defer {
cancel()
time.sleep(2 * time.millisecond) // give a small time window, in which the go thread routine has a chance to return
@ -93,7 +93,7 @@ const short_duration = 2 * time.millisecond // a reasonable duration to block in
fn main() {
dur := time.now().add(short_duration)
mut background := context.background()
mut ctx, cancel := context.with_deadline(mut &background, dur)
mut ctx, cancel := context.with_deadline(mut background, dur)
defer {
// Even though ctx will be expired, it is good practice to call its
@ -131,7 +131,7 @@ fn main() {
// Pass a context with a timeout to tell a blocking function that it
// should abandon its work after the timeout elapses.
mut background := context.background()
mut ctx, cancel := context.with_timeout(mut &background, short_duration)
mut ctx, cancel := context.with_timeout(mut background, short_duration)
defer {
cancel()
eprintln('> defer finishes')

View File

@ -32,7 +32,7 @@ fn test_with_cancel() {
}
mut background := context.background()
mut ctx, cancel := context.with_cancel(mut &background)
mut ctx, cancel := context.with_cancel(mut background)
defer {
cancel()
}

View File

@ -7,9 +7,6 @@ module context
import time
const (
background = EmptyContext(0)
todo = EmptyContext(1)
cancel_context_key = Key('context.CancelContext')
// canceled is the error returned by Context.err when the context is canceled.
@ -74,22 +71,6 @@ mut:
err() IError
}
// background returns an empty Context. It is never canceled, has no
// values, and has no deadline. It is typically used by the main function,
// initialization, and tests, and as the top-level Context for incoming
// requests.
pub fn background() Context {
return context.background
}
// todo returns an empty Context. Code should use todo when
// it's unclear which Context to use or it is not yet available (because the
// surrounding function has not yet been extended to accept a Context
// parameter).
pub fn todo() Context {
return context.todo
}
fn context_name(ctx Context) string {
return typeof(ctx)
}

View File

@ -11,7 +11,7 @@ const (
fn test_with_deadline() {
dur := time.now().add(short_duration)
mut background := context.background()
mut ctx, cancel := context.with_deadline(mut &background, dur)
mut ctx, cancel := context.with_deadline(mut background, dur)
defer {
// Even though ctx will be expired, it is good practice to call its
@ -35,7 +35,7 @@ fn test_with_timeout() {
// Pass a context with a timeout to tell a blocking function that it
// should abandon its work after the timeout elapses.
mut background := context.background()
mut ctx, cancel := context.with_timeout(mut &background, short_duration)
mut ctx, cancel := context.with_timeout(mut background, short_duration)
defer {
cancel()
}

View File

@ -6,9 +6,8 @@ module context
import time
// An EmptyContext is never canceled, has no values, and has no deadline. It is not
// struct{}, since vars of this type must have distinct addresses.
pub type EmptyContext = int
// An EmptyContext is never canceled, has no values.
pub struct EmptyContext {}
pub fn (ctx &EmptyContext) deadline() ?time.Time {
return none
@ -16,9 +15,7 @@ pub fn (ctx &EmptyContext) deadline() ?time.Time {
pub fn (ctx &EmptyContext) done() chan int {
ch := chan int{}
defer {
ch.close()
}
return ch
}
@ -31,11 +28,42 @@ pub fn (ctx &EmptyContext) value(key Key) ?Any {
}
pub fn (ctx &EmptyContext) str() string {
if ctx == background {
return 'context.Background'
}
if ctx == todo {
return 'context.TODO'
}
return 'unknown empty Context'
}
// A BackgroundContext is never canceled, has no values.
struct BackgroundContext {
EmptyContext
}
// str returns a string describing the Context.
pub fn (ctx &BackgroundContext) str() string {
return 'context.Background'
}
// background returns an empty Context. It is never canceled, has no
// values, and has no deadline. It is typically used by the main function,
// initialization, and tests, and as the top-level Context for incoming
// requests.
pub fn background() Context {
return &BackgroundContext{}
}
// A TodoContext is never canceled, has no values, and has no deadline. It is
// never used for real work.
struct TodoContext {
EmptyContext
}
// str returns a string describing the Context.
pub fn (ctx &TodoContext) str() string {
return 'context.TODO'
}
// todo returns an empty Context. Code should use todo when
// it's unclear which Context to use or it is not yet available (because the
// surrounding function has not yet been extended to accept a Context
// parameter).
pub fn todo() Context {
return &TodoContext{}
}

View File

@ -92,7 +92,7 @@ pub fn (mut octx OneContext) run() {
octx.run_multiple_contexts(mut wrapped_ctx)
for mut ctx in octx.ctxs {
octx.run_multiple_contexts(mut &ctx)
octx.run_multiple_contexts(mut ctx)
}
}

View File

@ -5,7 +5,7 @@ import time
fn eventually(ch chan int) bool {
mut background := context.background()
mut timeout, cancel := context.with_timeout(mut &background, 30 * time.millisecond)
mut timeout, cancel := context.with_timeout(mut background, 30 * time.millisecond)
defer {
cancel()
}
@ -27,32 +27,32 @@ struct Value {
val string
}
fn test_merge_nomilan() {
fn test_merge_nominal() {
mut background := context.background()
foo := &Value{
val: 'foo'
}
foo := 'foo'
mut value_ctx1 := context.with_value(background, 'foo', foo)
mut ctx1, cancel := context.with_cancel(mut &value_ctx1)
mut ctx1, cancel := context.with_cancel(mut value_ctx1)
defer {
cancel()
}
bar := &Value{
val: 'bar'
}
bar := 'bar'
mut value_ctx2 := context.with_value(background, 'bar', bar)
mut ctx2, _ := context.with_cancel(mut &value_ctx2)
mut ctx2, _ := context.with_cancel(mut value_ctx2)
mut ctx, cancel2 := merge(ctx1, ctx2)
if deadline := ctx.deadline() {
panic('this should never happen')
assert false
}
val1 := ctx.value('foo') or {
assert false
return
}
val1 := ctx.value('foo') or { panic('wrong value access for key `foo`') }
match val1 {
Value {
string {
assert foo == val1
}
else {
@ -60,9 +60,12 @@ fn test_merge_nomilan() {
}
}
val2 := ctx.value('bar') or { panic('wrong value access for key `bar`') }
val2 := ctx.value('bar') or {
assert false
return
}
match val2 {
Value {
string {
assert bar == val2
}
else {
@ -71,7 +74,7 @@ fn test_merge_nomilan() {
}
if _ := ctx.value('baz') {
panic('this should never happen')
assert false
}
assert !eventually(ctx.done())
@ -79,12 +82,12 @@ fn test_merge_nomilan() {
cancel2()
assert eventually(ctx.done())
assert ctx.err() is Error
assert ctx.err().str() == 'canceled context'
}
fn test_merge_deadline_context_1() {
mut background := context.background()
mut ctx1, cancel := context.with_timeout(mut &background, time.second)
mut ctx1, cancel := context.with_timeout(mut background, time.second)
defer {
cancel()
}
@ -94,14 +97,14 @@ fn test_merge_deadline_context_1() {
if deadline := ctx.deadline() {
assert deadline.unix_time() != 0
} else {
panic('this should never happen')
assert false
}
}
fn test_merge_deadline_context_2() {
mut background := context.background()
ctx1 := context.background()
mut ctx2, cancel := context.with_timeout(mut &background, time.second)
mut ctx2, cancel := context.with_timeout(mut background, time.second)
defer {
cancel()
}
@ -110,7 +113,7 @@ fn test_merge_deadline_context_2() {
if deadline := ctx.deadline() {
assert deadline.unix_time() != 0
} else {
panic('this should never happen')
assert false
}
}
@ -122,7 +125,7 @@ fn test_merge_deadline_context_n() {
for i in 0 .. 10 {
ctxs << context.background()
}
mut ctx_n, _ := context.with_timeout(mut &background, time.second)
mut ctx_n, _ := context.with_timeout(mut background, time.second)
ctxs << ctx_n
for i in 0 .. 10 {
@ -135,7 +138,7 @@ fn test_merge_deadline_context_n() {
assert ctx.err() is none
cancel()
assert eventually(ctx.done())
assert ctx.err() is Error
assert ctx.err().str() == 'canceled context'
}
fn test_merge_deadline_none() {
@ -145,7 +148,7 @@ fn test_merge_deadline_none() {
mut ctx, _ := merge(ctx1, ctx2)
if _ := ctx.deadline() {
panic('this should never happen')
assert false
}
}
@ -157,7 +160,7 @@ fn test_merge_cancel_two() {
cancel()
assert eventually(ctx.done())
assert ctx.err() is Error
assert ctx.err().str() == 'canceled context'
assert ctx.err().str() == 'canceled context'
}
@ -170,6 +173,6 @@ fn test_merge_cancel_multiple() {
cancel()
assert eventually(ctx.done())
assert ctx.err() is Error
assert ctx.err().str() == 'canceled context'
assert ctx.err().str() == 'canceled context'
}