1
+ import ulsp
2
+
3
+ global work_items
4
+
5
+ #############################
6
+ # JRPC server Calculator
7
+ #############################
8
+ class JRPC_Calc(jrpc_server)
9
+
10
+ method start(addr)
11
+ local sock, msg
12
+ if not (jrpc_server := JRPC_HTTPSocket(addr,"n")) then
13
+ write("server open(",addr,") ERROR: ", \&errortext | "Unknown") & fail
14
+
15
+ repeat {
16
+ msg := jrpc_server.get_msg() | next
17
+ case msg.get_kind() of {
18
+ "request" : thread handle_request(msg)
19
+ default:
20
+ write("jrpc:msg: " || msg.get_kind(), image(msg.get_content()))
21
+ }
22
+ }
23
+ end
24
+
25
+ method handle_request(msg)
26
+ local id := msg.get_id(),
27
+ x := integer(msg.get_params()[1]),
28
+ y := integer(msg.get_params()[2])
29
+
30
+ # uncomment to trigger some test failures
31
+ #if x = 9 then fail
32
+ case msg.get_method() of {
33
+ "+" : {jrpc_server.send_msg(msg.make_result_response(x + y))}
34
+ "-" : jrpc_server.send_msg(msg.make_result_response(x - y))
35
+ "*" : jrpc_server.send_msg(msg.make_result_response(x * y))
36
+ "/" : jrpc_server.send_msg(msg.make_result_response(x / y))
37
+ default: write("jrpc:request:unsupported: ", msg.get_method())
38
+ }
39
+
40
+ end
41
+ end
42
+
43
+ ###############################
44
+ # client
45
+ ###############################
46
+ class JRPC_client(jrpc_client)
47
+
48
+ method listen(addr)
49
+ if not (jrpc_client := JRPC_HTTPSocket(addr,"na")) then
50
+ stop("client open(", addr, ") ERROR: ", \&errortext | "Unknown")
51
+ end
52
+
53
+ method test(op, params, answer)
54
+ local id
55
+ static idx := 0, mtx := mutex()
56
+ critical mtx: id := idx +:=1
57
+ jrpc_client.send_msg(JRPC_Message().make_request(id, op, params))
58
+ work_items[id] := [op, params, answer]
59
+ end
60
+
61
+ method start()
62
+ local x := ?9, y := ?8+1
63
+ test("+", [x, y], x+y)
64
+ test("-", [x, y], x-y)
65
+ test("*", [x, y], x*y)
66
+ test("/", [x, y], x/y)
67
+ end
68
+
69
+ end
70
+
71
+ global port
72
+ procedure main()
73
+ local calc, client, jobset, addr, id, op, x, y, answer,
74
+ workers, i, response, job
75
+
76
+ addr := ":" || 5000 + ?1000
77
+ if &features == ("MacOS" | "MS Windows NT") then
78
+ addr := "127.0.0.1" || addr
79
+
80
+ client := JRPC_client()
81
+ calc := JRPC_Calc()
82
+ thread calc.start(addr)
83
+ client.listen(addr)
84
+ workers:=[]
85
+ work_items := mutex(table())
86
+ every !10 do put(workers, thread client.start())
87
+ every wait(!workers)
88
+ jobset:=set()
89
+ every insert(jobset, !*work_items)
90
+
91
+ every i := !(*work_items*2) do {
92
+ if *jobset = 0 then break
93
+ if response := client.jrpc_client.get_msg(100) then {
94
+ delete(jobset, id:=response.get_id())
95
+ job := work_items[id]
96
+ op:=job[1]; x:=job[2][1]; y:=job[2][2]; answer := job[3]
97
+ write(left(id, 2), ": ", x, " ", op, " ", y, " = ", right(response.get_result(), 3),
98
+ " ", if response.get_result()=answer then "Pass" else "Fail")
99
+ }
100
+ }
101
+
102
+ every job := work_items[id:=!jobset] do {
103
+ op:=job[1]; x:=job[2][1]; y:=job[2][2]
104
+ write(left(id, 2), ": ", x, " ", op, " ", y, " = Failed to get a response")
105
+ }
106
+
107
+ end
0 commit comments