rpc_lesson2¶
Three models run in a client-server, remote procedure call (RPC) communication pattern. The two client models (client1 & client2) send requests and receive response to/from the server model server via the deprecated call method. The server model receives requests and send responses. This example demostrates the RPC pattern through the use of the client_of and is_server model parameters and the RPC interface classes/functions. The client1 & client2 models also send request/response pairs to files in the temporary directory and receive parameters via the command line as specified in the YAML (both model call the same source code). The server model receives parameters as input from a file.
C Version¶
Model Code:
1#include "YggInterface.h"
2#include <stdio.h>
3
4
5int get_fibonacci(int n) {
6 int pprev = 0, prev = 1, result = 1, fib_no = 1;
7 while (fib_no < n) {
8 result = prev + pprev;
9 pprev = prev;
10 prev = result;
11 fib_no = fib_no + 1;
12 }
13 return result;
14};
15
16
17int main(int argc, char *argv[]) {
18
19 int exit_code = 0;
20 printf("Hello from C server!\n");
21
22 // Create server-side rpc conneciton using model name
23 yggRpc_t rpc = yggRpcServer("server", "%d", "%d");
24
25 // Continue receiving requests until the connection is closed when all
26 // clients have disconnected.
27 int flag, n, result;
28 while (1) {
29 printf("server(C): receiving...\n");
30 flag = rpcRecv(rpc, &n);
31 if (flag < 0) {
32 printf("server(C): end of input\n");
33 break;
34 }
35
36 // Compute fibonacci number
37 printf("server(C): Received request for Fibonacci number %d\n", n);
38 result = get_fibonacci(n);
39 printf("server(C): Sending response for Fibonacci number %d: %d\n",
40 n, result);
41
42 // Send response back
43 flag = rpcSend(rpc, result);
44 if (flag < 0) {
45 printf("server(C): ERROR sending\n");
46 exit_code = -1;
47 break;
48 }
49 }
50
51 printf("Goodbye from C server\n");
52 return exit_code;
53};
1#include "YggInterface.h"
2#include <stdio.h>
3
4
5int main(int argc, char *argv[]) {
6
7 int iterations = atoi(argv[1]);
8 int client_index = atoi(argv[2]);
9 int exit_code = 0;
10 printf("Hello from C client%d: iterations %d\n",
11 client_index, iterations);
12
13 // Set up connections matching yaml
14 // RPC client-side connection will be $(server_name)_$(client_name)
15 char rpc_name[100];
16 char log_name[100];
17 sprintf(rpc_name, "server_client%d", client_index);
18 sprintf(log_name, "output_log%d", client_index);
19 yggRpc_t rpc = yggRpcClient(rpc_name, "%d", "%d");
20 yggOutput_t log = yggOutputFmt(log_name, "fib(%-2d) = %-2d\n");
21
22 // Initialize variables
23 int ret = 0;
24 int fib = -1;
25 int i;
26
27 // Iterate over Fibonacci sequence
28 for (i = 1; i <= iterations; i++) {
29
30 // Call the server and receive response
31 printf("client%d(C): Calling fib(%d)\n", client_index, i);
32 ret = rpcCall(rpc, i, &fib);
33 if (ret < 0) {
34 printf("client%d(C): RPC CALL ERROR\n", client_index);
35 exit_code = -1;
36 break;
37 }
38 printf("client%d(C): Response fib(%d) = %d\n", client_index, i, fib);
39
40 // Log result by sending it to the log connection
41 ret = yggSend(log, i, fib);
42 if (ret < 0) {
43 printf("client%d(C): SEND ERROR\n", client_index);
44 exit_code = -1;
45 break;
46 }
47 }
48
49 printf("Goodbye from C client%d\n", client_index);
50 return exit_code;
51
52}
53
Model YAML:
1---
2
3model:
4 name: server
5 language: c
6 args: ./src/server.c
7 is_server: True # Creates a RPC server queue called "server"
1---
2
3models:
4 - name: client1
5 language: c
6 args:
7 - ./src/client.c
8 - 3 # Pass the number of iterations that should be performed
9 - 1 # Pass index of the client
10 client_of: server # Creates an RPC client queue "server_client"
11 outputs: output_log1
12 - name: client2
13 language: c
14 args:
15 - ./src/client.c
16 - 5 # Pass the number of iterations that should be performed
17 - 2 # Pass index of the client
18 client_of: server # Creates an RPC client queue "server_client"
19 outputs: output_log2
20
21connections:
22 - input: output_log1
23 output: client_output1.txt
24 in_temp: true
25 - input: output_log2
26 output: client_output2.txt
27 in_temp: true
C++ Version¶
Model Code:
1#include "YggInterface.hpp"
2#include <stdio.h>
3
4
5int get_fibonacci(int n) {
6 int pprev = 0, prev = 1, result = 1, fib_no = 1;
7 while (fib_no < n) {
8 result = prev + pprev;
9 pprev = prev;
10 prev = result;
11 fib_no = fib_no + 1;
12 }
13 return result;
14};
15
16
17int main(int argc, char *argv[]) {
18
19 int exit_code = 0;
20 printf("Hello from C++ server!\n");
21
22 // Create server-side rpc conneciton using model name
23 YggRpcServer rpc("server", "%d", "%d");
24
25 // Continue receiving requests until the connection is closed when all
26 // clients have disconnected.
27 int flag, n, result;
28 while (1) {
29 printf("server(C++): receiving...\n");
30 flag = rpc.recv(1, &n);
31 if (flag < 0) {
32 printf("server(C++): end of input\n");
33 break;
34 }
35
36 // Compute fibonacci number
37 printf("server(C++): Received request for Fibonacci number %d\n", n);
38 result = get_fibonacci(n);
39 printf("server(C++): Sending response for Fibonacci number %d: %d\n",
40 n, result);
41
42 // Send response back
43 flag = rpc.send(1, result);
44 if (flag < 0) {
45 printf("server(C++): ERROR sending\n");
46 exit_code = -1;
47 break;
48 }
49 }
50
51 printf("Goodbye from C++ server\n");
52 return exit_code;
53};
1#include "YggInterface.hpp"
2#include <stdio.h>
3
4
5int main(int argc, char *argv[]) {
6
7 int iterations = atoi(argv[1]);
8 int client_index = atoi(argv[2]);
9 int exit_code = 0;
10 printf("Hello from C++ client%d: iterations %d\n",
11 client_index, iterations);
12
13 // Set up connections matching yaml
14 // RPC client-side connection will be $(server_name)_$(client_name)
15 char rpc_name[100];
16 char log_name[100];
17 sprintf(rpc_name, "server_client%d", client_index);
18 sprintf(log_name, "output_log%d", client_index);
19 YggRpcClient rpc(rpc_name, "%d", "%d");
20 YggOutput log(log_name, "fib(%-2d) = %-2d\n");
21
22 // Initialize variables
23 int ret = 0;
24 int fib = -1;
25 char *logmsg = (char*)malloc(YGG_MSG_MAX*sizeof(char));
26 int i;
27
28 // Iterate over Fibonacci sequence
29 for (i = 1; i <= iterations; i++) {
30
31 // Call the server and receive response
32 printf("client%d(C++): Calling fib(%d)\n", client_index, i);
33 ret = rpc.call(2, i, &fib);
34 if (ret < 0) {
35 printf("client%d(C++): RPC CALL ERROR\n", client_index);
36 exit_code = -1;
37 break;
38 }
39 printf("client%d(C++): Response fib(%d) = %d\n", client_index, i, fib);
40
41 // Log result by sending it to the log connection
42 ret = log.send(2, i, fib);
43 if (ret < 0) {
44 printf("client%d(C++): SEND ERROR\n", client_index);
45 exit_code = -1;
46 break;
47 }
48 }
49
50 free(logmsg);
51 printf("Goodbye from C++ client%d\n", client_index);
52 return exit_code;
53}
Model YAML:
1---
2
3model:
4 name: server
5 language: c++
6 args: ./src/server.cpp
7 is_server: True # Creates a RPC server queue called "server"
1---
2
3models:
4 - name: client1
5 language: c++
6 args:
7 - ./src/client.cpp
8 - 3 # Pass the number of iterations that should be performed
9 - 1 # Pass index of the client
10 client_of: server # Creates an RPC client queue "server_client"
11 outputs: output_log1
12 - name: client2
13 language: c++
14 args:
15 - ./src/client.cpp
16 - 5 # Pass the number of iterations that should be performed
17 - 2 # Pass index of the client
18 client_of: server # Creates an RPC client queue "server_client"
19 outputs: output_log2
20
21connections:
22 - input: output_log1
23 output: client_output1.txt
24 in_temp: true
25 - input: output_log2
26 output: client_output2.txt
27 in_temp: true
Fortran Version¶
Model Code:
1program main
2 use fygg
3
4 interface
5 function get_fibonacci(n) result(out)
6 integer, intent(in) :: n
7 integer :: out
8 end function get_fibonacci
9 end interface
10
11 type(yggcomm) :: rpc
12 logical :: ret
13 integer :: fib, n
14 integer :: exit_code = 0
15
16 write(*, '("Hello from Fortran server!")')
17
18 ! Create server-side rpc conneciton using model name
19 rpc = ygg_rpc_server("server", "%d", "%d")
20
21 ! Initialize variables
22 ret = .true.
23 fib = -1
24
25 ! Continue receiving requests until the connection is closed when all
26 ! clients have disconnected.
27 do while (.TRUE.)
28 write(*, '("server(F): receiving...")')
29 ret = ygg_recv_var(rpc, yggarg(n))
30 if (.not.ret) then
31 write(*, '("server(F): end of input")')
32 exit
33 end if
34
35 ! Compute fibonacci number
36 write(*, '("server(F): Received request for Fibonacci number ",i2)') n
37 fib = get_fibonacci(n)
38 write(*, '("server(F): Sending response for Fibonacci number ",i2,": ",i2)') n, fib
39
40 ! Send response back
41 ret = ygg_send_var(rpc, yggarg(fib))
42 if (.not.ret) then
43 write(*, '("server(F): ERROR sending")')
44 exit_code = -1;
45 exit;
46 end if
47 end do
48
49 write(*, '("Goodbye from Fortran server")')
50 if (exit_code.lt.0) then
51 stop 1
52 end if
53
54end program main
55
56function get_fibonacci(n) result(out)
57 integer, intent(in) :: n
58 integer :: out
59 integer :: pprev, prev, fib_no
60 pprev = 0
61 prev = 1
62 out = 1
63 fib_no = 1
64 do while (fib_no < n)
65 out = prev + pprev
66 pprev = prev
67 prev = out
68 fib_no = fib_no + 1
69 end do
70end function get_fibonacci
1program main
2 use fygg
3
4 character(len=32) :: arg
5 integer :: iterations, client_index
6 type(yggcomm) :: rpc
7 type(yggcomm) :: log
8 logical :: ret
9 integer :: fib, i
10 integer :: exit_code = 0
11 character(len=100) :: rpc_name
12 character(len=100) :: log_name
13
14 call get_command_argument(1, arg)
15 read(arg, *) iterations
16 call get_command_argument(2, arg)
17 read(arg, *) client_index
18 write(*, '("Hello from Fortran client",i1,": iterations ",i2)') &
19 client_index, iterations
20
21 ! Set up connections matching yaml
22 ! RPC client-side connection will be $(server_name)_$(client_name)
23 write(rpc_name, '("server_client",i1)') client_index
24 write(log_name, '("output_log",i1)') client_index
25 rpc = ygg_rpc_client(trim(rpc_name), "%d", "%d")
26 log = ygg_output_fmt(trim(log_name), "fib(%-2d) = %-2d\n")
27
28 ! Initialize variables
29 ret = .true.
30 fib = -1
31
32 ! Iterate over Fibonacci sequence
33 do i = 1, iterations
34
35 ! Call the server and receive response
36 write(*, '("client",i1,"(F): Calling fib(",i2,")")') &
37 client_index, i
38 ret = ygg_rpc_call(rpc, yggarg(i), yggarg(fib))
39 if (.not.ret) then
40 write(*, '("client",i1,"(F): RPC CALL ERROR")') client_index
41 exit_code = -1;
42 exit
43 end if
44 write(*, '("client",i1,"(F): Response fib(",i2,") = ",i2)') &
45 client_index, i, fib
46
47 ! Log result by sending it to the log connection
48 ret = ygg_send_var(log, [yggarg(i), yggarg(fib)])
49 if (.not.ret) then
50 write(*, '("client",i1,"(F): SEND ERROR")') client_index
51 exit_code = -1
52 exit
53 end if
54
55 end do
56
57 write(*, '("Goodbye from Fortran client",i1)') client_index
58 if (exit_code.lt.0) then
59 stop 1
60 end if
61
62end program main
Model YAML:
1---
2
3model:
4 name: server
5 language: fortran
6 args: ./src/server.f90
7 is_server: True # Creates a RPC server queue called "server"
1---
2
3models:
4 - name: client1
5 language: fortran
6 args:
7 - ./src/client.f90
8 - 3 # Pass the number of iterations that should be performed
9 - 1 # Pass index of the client
10 client_of: server # Creates an RPC client queue "server_client"
11 outputs: output_log1
12 - name: client2
13 language: fortran
14 args:
15 - ./src/client.f90
16 - 5 # Pass the number of iterations that should be performed
17 - 2 # Pass index of the client
18 client_of: server # Creates an RPC client queue "server_client"
19 outputs: output_log2
20
21connections:
22 - input: output_log1
23 output: client_output1.txt
24 in_temp: true
25 - input: output_log2
26 output: client_output2.txt
27 in_temp: true
Julia Version¶
Model Code:
1using Yggdrasil
2using Printf
3
4
5function get_fibonacci(n)
6 global pprev = 0
7 global prev = 1
8 global result = 1
9 global fib_no = 1
10 while (fib_no < n)
11 global result = prev + pprev
12 global pprev = prev
13 global prev = result
14 global fib_no = fib_no + 1
15 end
16 return Int64(result)
17end
18
19
20function main()
21
22 println("Hello from Julia server!")
23
24 # Create server-side rpc conneciton using model name
25 rpc = Yggdrasil.YggInterface("YggRpcServer", "server", "%d", "%d")
26
27 # Continue receiving requests until the connection is closed when all
28 # clients have disconnected.
29 while (true)
30 println("server(Julia): receiving...")
31 retval, rpc_in = rpc.recv()
32 if (!retval)
33 println("server(Julia): end of input")
34 break
35 end
36
37 # Compute fibonacci number
38 n = rpc_in[1]
39 @printf("server(Julia): Received request for Fibonacci number %d\n", n)
40 result = get_fibonacci(n)
41 @printf("server(Julia): Sending response for Fibonacci number %d: %d\n", n, result)
42
43 # Send response back
44 flag = rpc.send(result)
45 if (!flag)
46 error("server(Julia): ERROR sending")
47 end
48 end
49
50 println("Goodbye from Julia server")
51end
52
53main()
1using Yggdrasil
2using Printf
3
4
5function main(iterations, client_index)
6
7 @printf("Hello from Julia client: iterations = %d\n", iterations)
8
9 # Set up connections matching yaml
10 # RPC client-side connection will be $(server_name)_$(client_name)
11 rpc = Yggdrasil.YggInterface("YggRpcClient", @sprintf("server_client%d", client_index), "%d", "%d")
12 log = Yggdrasil.YggInterface("YggOutput", @sprintf("output_log%d", client_index), "fib(%-2d) = %-2d\n")
13
14 # Iterate over Fibonacci sequence
15 for i = 1:iterations
16
17 # Call the server and receive response
18 @printf("client%d(Julia): Calling fib(%d)\n", client_index, i)
19 ret, result = rpc.call(i)
20 if (!ret)
21 error(@sprintf("client%d(Julia): RPC CALL ERROR", client_index))
22 end
23 fib = result[1]
24 @printf("client%d(Julia): Response fib(%d) = %d\n", client_index, i, fib)
25
26 # Log result by sending it to the log connection
27 ret = log.send(i, fib)
28 if (!ret)
29 error(@sprintf("client%d(Julia): SEND ERROR", client_index))
30 end
31 end
32
33 @printf("Goodbye from Julia client%d\n", client_index)
34end
35
36
37main(parse(Int64, ARGS[1]), parse(Int64, ARGS[2]))
Model YAML:
1---
2
3model:
4 name: server
5 language: julia
6 args: ./src/server.jl
7 is_server: True # Creates a RPC server queue called "server"
1---
2
3models:
4 - name: client1
5 language: julia
6 args:
7 - ./src/client.jl
8 - 3 # Pass the number of iterations that should be performed
9 - 1 # Pass index of the client
10 client_of: server # Creates an RPC client queue "server_client"
11 outputs: output_log1
12 - name: client2
13 language: julia
14 args:
15 - ./src/client.jl
16 - 5 # Pass the number of iterations that should be performed
17 - 2 # Pass index of the client
18 client_of: server # Creates an RPC client queue "server_client"
19 outputs: output_log2
20
21connections:
22 - input: output_log1
23 output: client_output1.txt
24 in_temp: true
25 - input: output_log2
26 output: client_output2.txt
27 in_temp: true
Matlab Version¶
Model Code:
1function server()
2
3 disp('Hello from Matlab server!');
4
5 % Create server-side rpc conneciton using model name
6 rpc = YggInterface('YggRpcServer', 'server', '%d', '%d');
7
8 % Continue receiving requests until the connection is closed when all
9 % clients have disconnected.
10 while true
11 disp('server(M): receiving...');
12 [retval, rpc_in] = rpc.recv();
13 if (~retval);
14 disp('server(M):end of input');
15 break;
16 end;
17
18 % Compute fibonacci number
19 n = rpc_in{1};
20 fprintf('server(M): Received request for Fibonacci number %d\n', n);
21 pprev = 0;
22 prev = 1;
23 result = 1;
24 fib_no = 1;
25 while fib_no < n
26 result = prev + pprev;
27 pprev = prev;
28 prev = result;
29 fib_no = fib_no + 1;
30 end;
31 fprintf('server(M): Sending response for Fibonacci number %d: %d\n', n, result);
32
33 % Send response back
34 flag = rpc.send(int32(result));
35 if (~flag);
36 error('server(M): ERROR sending');
37 end;
38 end;
39
40 disp('Goodbye from Matlab server');
41
42end
1function client(iterations, client_index)
2
3 iterations = str2num(iterations);
4 client_index = str2num(client_index);
5 fprintf('Hello from Matlab client%d: iterations = %d\n', ...
6 client_index, iterations);
7
8 % Set up connections matching yaml
9 % RPC client-side connection will be $(server_name)_$(client_name)
10 rpc_name = sprintf('server_client%d', client_index);
11 log_name = sprintf('output_log%d', client_index);
12 rpc = YggInterface('YggRpcClient', rpc_name, '%d', '%d');
13 log = YggInterface('YggOutput', log_name, 'fib(%-2d) = %-2d\n');
14
15 % Iterate over Fibonacci sequence
16 for i = 1:iterations
17
18 % Call the server and receive response
19 fprintf('client%d(Matlab): Calling fib(%d)\n', client_index, i);
20 [ret, result] = rpc.call(int32(i));
21 if (~ret);
22 error(sprintf('client%d(Matlab): RPC CALL ERROR\n', client_index));
23 end;
24 fib = result{1};
25 fprintf('client%d(Matlab): Response fib(%d) = %d\n', client_index, ...
26 i, fib);
27
28 % Log result by sending it to the log connection
29 ret = log.send(int32(i), fib);
30 if (~ret);
31 error(sprintf('client%d(Matlab): SEND ERROR\n', client_index));
32 end;
33 end;
34
35 fprintf('Goodbye from Matlab client%d\n', client_index);
36
37end
Model YAML:
1---
2
3model:
4 name: server
5 language: matlab
6 args: ./src/server.m
7 is_server: True # Creates a RPC server queue called "server"
1---
2
3models:
4 - name: client1
5 language: matlab
6 args:
7 - ./src/client.m
8 - 3 # Pass the number of iterations that should be performed
9 - 1 # Pass index of the client
10 client_of: server # Creates an RPC client queue "server_client"
11 outputs: output_log1
12 - name: client2
13 language: matlab
14 args:
15 - ./src/client.m
16 - 5 # Pass the number of iterations that should be performed
17 - 2 # Pass index of the client
18 client_of: server # Creates an RPC client queue "server_client"
19 outputs: output_log2
20
21connections:
22 - input: output_log1
23 output: client_output1.txt
24 in_temp: true
25 - input: output_log2
26 output: client_output2.txt
27 in_temp: true
Python Version¶
Model Code:
1import numpy as np
2from yggdrasil.interface.YggInterface import YggInput, YggRpcServer
3
4
5def get_fibonacci(n):
6 r"""Compute the nth number of the Fibonacci sequence.
7
8 Args:
9 n (int): Index of the Fibonacci number in the Fibonacci sequence that
10 should be returned.
11
12 Returns:
13 int: The nth Fibonacci number.
14
15 """
16 pprev = 0
17 prev = 1
18 result = 1
19 fib_no = 1
20 while fib_no < n:
21 result = prev + pprev
22 pprev = prev
23 prev = result
24 fib_no = fib_no + 1
25 return result
26
27
28def main():
29 r"""Function to execute server communication and computation in a loop."""
30
31 print('Hello from Python server!')
32
33 # Get parameters
34 inp = YggInput("params")
35 retval, params = inp.recv()
36 if not retval:
37 raise RuntimeError('server: ERROR receiving parameters')
38 print('server: Parameters = %s' % params)
39
40 # Create server-side rpc conneciton using model name
41 rpc = YggRpcServer("server", "%d", "%d")
42
43 # Continue receiving requests until the connection is closed when all
44 # clients have disconnected.
45 while True:
46 print('server: receiving...')
47 retval, rpc_in = rpc.recv()
48 if not retval:
49 print('server: end of input')
50 break
51
52 # Compute fibonacci number
53 n = rpc_in[0]
54 print('server: Received request for Fibonacci number %d' % n)
55 result = get_fibonacci(n)
56 print('server: Sending response for Fibonacci number %d: %d' % (n, result))
57
58 # Send response back
59 flag = rpc.send(np.int32(result))
60 if not flag:
61 raise RuntimeError('server: ERROR sending')
62
63 print('Goodbye from Python server')
64
65
66if __name__ == '__main__':
67 main()
1import sys
2import numpy as np
3from yggdrasil.interface.YggInterface import (
4 YggRpcClient, YggOutput)
5
6
7def main(iterations, client_index):
8 r"""Function to execute client communication with server that computes
9 numbers in the Fibonacci sequence.
10
11 Args:
12 iterations (int): The number of Fibonacci numbers to log.
13 client_index (int): Index of the client in total list of clients.
14
15 """
16
17 print('Hello from Python client%d: iterations = %d ' % (client_index,
18 iterations))
19
20 # Set up connections matching yaml
21 # RPC client-side connection will be $(server_name)_$(client_name)
22 rpc = YggRpcClient("server_client%d" % client_index, "%d", "%d")
23 log = YggOutput("output_log%d" % client_index, 'fib(%-2d) = %-2d\n')
24
25 # Iterate over Fibonacci sequence
26 for i in range(1, iterations + 1):
27
28 # Call the server and receive response
29 print('client%d(Python): Calling fib(%d)' % (client_index, i))
30 ret, result = rpc.call(np.int32(i))
31 if not ret:
32 raise RuntimeError('client%d(Python): RPC CALL ERROR' % client_index)
33 fib = result[0]
34 print('client%d(Python): Response fib(%d) = %d' % (client_index, i, fib))
35
36 # Log result by sending it to the log connection
37 ret = log.send(np.int32(i), fib)
38 if not ret:
39 raise RuntimeError('client%d(Python): SEND ERROR' % client_index)
40
41 print('Goodbye from Python client%d' % client_index)
42
43
44if __name__ == '__main__':
45 # Take number of iterations from the first argument and the
46 # client index from the second
47 main(int(sys.argv[1]), int(sys.argv[2]))
Model YAML:
1---
2
3model:
4 name: server
5 language: python
6 args: ./src/server.py
7 is_server: True # Creates a RPC server queue called "server"
8 inputs:
9 name: params
10 default_file:
11 name: ./Input/server_params.txt
12 filetype: ascii
1---
2
3models:
4 - name: client1
5 language: python
6 args:
7 - ./src/client.py
8 - 3 # Pass the number of iterations that should be performed
9 - 1 # Pass index of the client
10 client_of: server # Creates an RPC client queue "server_client"
11 outputs: output_log1
12 - name: client2
13 language: python
14 args:
15 - ./src/client.py
16 - 5 # Pass the number of iterations that should be performed
17 - 2 # Pass index of the client
18 client_of: server # Creates an RPC client queue "server_client"
19 outputs: output_log2
20
21connections:
22 - input: output_log1
23 output: client_output1.txt
24 in_temp: true
25 - input: output_log2
26 output: client_output2.txt
27 in_temp: true
R Version¶
Model Code:
1library(yggdrasil)
2
3
4get_fibonacci <- function(n) {
5 pprev = 0
6 prev = 1
7 result = 1
8 fib_no = 1
9 while (fib_no < n) {
10 result = prev + pprev
11 pprev = prev
12 prev = result
13 fib_no = fib_no + 1
14 }
15 return(as.integer(result))
16}
17
18
19main <- function() {
20
21 fprintf('Hello from R server!')
22
23 # Create server-side rpc conneciton using model name
24 rpc <- YggInterface('YggRpcServer', "server", "%d", "%d")
25
26 # Continue receiving requests until the connection is closed when all
27 # clients have disconnected.
28 while (1) {
29 fprintf('server(R): receiving...')
30 c(retval, rpc_in) %<-% rpc$recv()
31 if (!retval) {
32 fprintf('server(R): end of input')
33 break
34 }
35
36 # Compute fibonacci number
37 n = rpc_in[[1]]
38 fprintf('server(R): Received request for Fibonacci number %d', n)
39 result = get_fibonacci(n)
40 fprintf('server(R): Sending response for Fibonacci number %d: %d', n, result)
41
42 # Send response back
43 flag <- rpc$send(result)
44 if (!flag) {
45 stop('server(R): ERROR sending')
46 }
47
48 }
49
50 print('Goodbye from R server')
51}
52
53main()
1library(yggdrasil)
2
3
4main <- function(iterations, client_index) {
5
6 fprintf('Hello from Python client: iterations = %d ', iterations)
7
8 # Set up connections matching yaml
9 # RPC client-side connection will be $(server_name)_$(client_name)
10 rpc <- YggInterface('YggRpcClient',
11 sprintf("server_client%d", client_index), "%d", "%d")
12 log <- YggInterface('YggOutput',
13 sprintf("output_log%d", client_index), 'fib(%-2d) = %-2d\n')
14
15 # Iterate over Fibonacci sequence
16 for (i in 1:iterations) {
17
18 # Call the server and receive response
19 fprintf('client%d(R): Calling fib(%d)', client_index, i)
20 c(ret, result) %<-% rpc$call(i)
21 if (!ret) {
22 stop(sprintf('client%d(R): RPC CALL ERROR', client_index))
23 }
24 fib <- result[[1]]
25 fprintf('client%d(R): Response fib(%d) = %d', client_index, i, fib)
26
27 # Log result by sending it to the log connection
28 ret <- log$send(i, fib)
29 if (!ret) {
30 stop(sprintf('client%d(R): SEND ERROR', client_index))
31 }
32 }
33
34 fprintf('Goodbye from R client%d', client_index)
35}
36
37
38args = commandArgs(trailingOnly=TRUE)
39main(strtoi(args[[1]]), strtoi(args[[2]]))
Model YAML:
1---
2
3model:
4 name: server
5 language: R
6 args: ./src/server.R
7 is_server: True # Creates a RPC server queue called "server"
1---
2
3models:
4 - name: client1
5 language: R
6 args:
7 - ./src/client.R
8 - 3 # Pass the number of iterations that should be performed
9 - 1 # Pass index of the client
10 client_of: server # Creates an RPC client queue "server_client"
11 outputs: output_log1
12 - name: client2
13 language: R
14 args:
15 - ./src/client.R
16 - 5 # Pass the number of iterations that should be performed
17 - 2 # Pass index of the client
18 client_of: server # Creates an RPC client queue "server_client"
19 outputs: output_log2
20
21connections:
22 - input: output_log1
23 output: client_output1.txt
24 in_temp: true
25 - input: output_log2
26 output: client_output2.txt
27 in_temp: true