70 lines
1.7 KiB
Nim
Raw Permalink Normal View History

2024-02-21 19:51:43 -07:00
import std/os
import chronos
import chronos/threadsync
import chronos/unittest2/asynctests
import taskpools
2024-02-21 22:56:17 -07:00
## This example mocks up a sequence and uses
## a finalizer and GC_fullCollect to more
## deterministically create a memory error.
##
## see `exFailureSeq.nim` for a probablisitc based
## example using a real seq object.
##
2024-02-21 20:07:24 -07:00
type
2024-02-21 22:12:55 -07:00
Seq*[T] = object
2024-02-21 22:11:50 -07:00
data*: ptr UncheckedArray[T]
size*: int
2024-02-21 22:12:55 -07:00
2024-02-21 20:07:24 -07:00
DataObj = ref object
2024-02-21 22:19:00 -07:00
mockSeq: Seq[char]
2024-02-21 20:07:24 -07:00
2024-02-21 22:12:55 -07:00
template toOpenArray*[T](arr: Seq[T]): auto =
2024-02-21 22:11:50 -07:00
system.toOpenArray(arr.data, 0, arr.size)
2024-02-21 22:24:16 -07:00
proc worker(data: ptr Seq[char], sig: ThreadSignalPtr) =
2024-02-21 20:26:08 -07:00
os.sleep(1_000)
2024-02-21 22:13:45 -07:00
echo "running worker: "
2024-02-21 22:09:34 -07:00
assert data[].data != nil
2024-02-21 22:04:43 -07:00
echo "worker: ", data[].toOpenArray()
2024-02-21 22:24:16 -07:00
discard sig.fireSync()
2024-02-21 19:51:43 -07:00
2024-02-21 20:07:24 -07:00
proc finalizer(obj: DataObj) =
2024-02-21 22:26:40 -07:00
echo "finalize DataObj and freeing mockSeq"
2024-02-21 22:19:00 -07:00
obj.mockSeq.data.dealloc()
obj.mockSeq.data = nil
proc initMockSeq(msg: string): Seq[char] =
result.data = cast[ptr UncheckedArray[char]](alloc0(13))
for i, c in msg:
result.data[i] = c
result.size = 12
2024-02-21 20:07:24 -07:00
2024-02-21 22:24:16 -07:00
proc runTest(tp: TaskPool, sig: ThreadSignalPtr) {.async.} =
2024-02-21 20:07:24 -07:00
## init
2024-02-21 22:15:54 -07:00
var obj: DataObj
2024-02-21 22:24:16 -07:00
obj.new(finalizer)
2024-02-21 22:19:00 -07:00
obj.mockSeq = initMockSeq("hello world!")
2024-02-21 20:07:24 -07:00
echo "spawn worker"
2024-02-21 22:24:16 -07:00
tp.spawn worker(addr obj.mockSeq, sig)
2024-02-21 20:07:24 -07:00
2024-02-21 22:26:40 -07:00
## adding fut.wait(100.milliseconds) creates memory issue
2024-02-26 17:23:45 -07:00
await wait(sig)
2024-02-21 22:33:01 -07:00
## just doing the wait is fine:
2024-02-21 22:26:40 -07:00
# await wait(sig)
2024-02-21 20:07:24 -07:00
2024-02-21 19:51:43 -07:00
suite "async tests":
var tp = Taskpool.new(num_threads = 2) # Default to the number of hardware threads.
2024-02-21 22:24:16 -07:00
let sig = ThreadSignalPtr.new().get()
2024-02-21 19:51:43 -07:00
asyncTest "test":
2024-02-21 20:26:08 -07:00
try:
2024-02-26 17:23:45 -07:00
await runTest(tp, sig).wait(100.milliseconds)
2024-02-21 22:09:34 -07:00
except AsyncTimeoutError:
2024-02-21 20:26:08 -07:00
echo "Run GC"
GC_fullCollect()
os.sleep(2_000)
echo "Done"