Remote block execution is supported using one of the existing networking abstractions, Remote Procedure Calls. This provides users the capabilities of executing the blocks on a remote machine while making it clear that the input function is being executed remotely.
Transparency about the location of the execution allows the students to experience the impact of network latency when accessing network resources and, more importantly, how this latency can be mitigated using techniques such as batching.
An example of a block function executed on the server is provided in Figure 62. In this example, the provided function is converting the movie idsvariable (referenced in an outer
scope) into the corresponding movie title using themapblock. After executing themapblock, the result is then returned by the given closure and returned to the user as the result of the call RPC. For large lists of movie ids, this approach can easily demonstrate the benefits of batching network requests as opposed to simply calling them in serial.
Figure 62: Batching RPC Requests
The remote execution of the RPC is a concept that is exposed to the user and this is reflected in the semantics of the execution RPC. When referencing dependencies from an outer scope, such as variables or other scripts, the function is evaluated with a copy of the given dependencies. Changes to local copies of variables are not reflected in the execution of functions that are executing on the server. Similarly, changes to other dependencies, such as custom block definitions or dependent scripts, are also not reflected in the remote execution of functions.
Modifications to remote copies of variables and project state behave similarly. Although the executed function may have modified dependencies from an outer scope, such as changing the values of variables in the outer scope, these changes are not synchronized with edits on the client. After executing the blocks on the server, the user is only provided with the output of the function. Any modifications to any of the copied dependencies of the block function are discarded.
Figure 63: Setting Variable During Remote Block Execution
A clarifying example is provided in Figure 63. Here, the function is simply setting an enclosed variable and then returning that the given variable has been updated. When this function is evaluated on the server, a copy of the variable, enclosed var, is serialized and submitted with the function to the server. The function is then compiled and executed on the server and the result is returned to the user. As the value of enclosed varis never used in the function, the update toenclosed varhas no impact on the execution of the function nor the user’s environment.
3.3.2 Modified Block Implementations
When executing blocks remotely, a number of the blocks require modifications to ensure the desired behavior during execution. This includes both removing unsupported function- ality and updating block implementations.
One obvious example of block implementation modification are blocks pertaining to the visual appearance of sprites and the stage. This includes blocks modifying the graphic effects, using the “pen” and changing the costume. These and blocks relating to audio or user input also perform no operation when executed remotely. Surprisingly, the motion blocks need to be functional on the server as these blocks could be used to provide an alternative way to perform various simple mathematical operations. For example, the motion blocks could be used to perform conversions between polar and Cartesian coordinate systems as shown in Figure 64. Although this would be an unorthodox use of the remote block execution functionality, the function is certainly well-defined and should be supported.
Figure 64: Converting Point from Polar to Cartesian
As the blocks are no longer executing in a Role, the networking blocks also require modifications to their underlying implementations. However, as the blocks are not executing on the actual client, some block behavior must be precisely defined and could be ambiguous.
One such ambiguity lies in the address of the executing code when performing network operations. Both RPCs and message passing can involve sending a response or result to the originating client. When executing blocks on the server (on the behalf of the given user), it is not immediately clear if the executing function should simply use the same address as the originating client or if it should have its own unique address.
One simple case is the use of the callRPC block which invokes a remote function and returns the result. These blocks should certainly recognize the executing function as the recipient and the result of the RPC request should be the returned by the given callRPC block. This is also consistent with the expected usage as this supports the batching of RPC invocations and returning a list of the results for each individual invocation.
A more complex case arises when considering invoking RPCs which send messages to the sender as with the “Earthquakes” Service. As the results of these RPCs are returned indirectly as a stream of messages rather than as a simple response, the resultant data should
be sent to the user when batching these RPC requests. Although sending the resulting streams of data back to the function could still be captured by dependent functions and returned to the user, this approach would be significantly more complex and likely too difficult for even more advanced programmers. Sending the resulting streams of messages back to the user suggests that the functions executed remotely should be evaluated in a context which shares the same address as the originating client. That is, the blocks should be executed as if the originating client executed them.