コード例 #1
0
ファイル: Api.cs プロジェクト: ichaos/Shovel
 public static Exception VmUserDefinedPrimitiveError(Shovel.Vm.Vm vm)
 {
     return(vm.UserDefinedPrimitiveError);
 }
コード例 #2
0
ファイル: Main.cs プロジェクト: ichaos/Shovel
        public static void Client()
        {
            Console.WriteLine("***");
            var program  = @"
// Setting up the call on the client.
var sourceAccountNo = @getSourceAccountNo()
var destinationAccountNo = @getDestinationAccountNo()
var amount = @getAmount()

// Go to the server.
@goToServer()

// Run the code on the server (the code on the server will wrap
// the code between 'goToServer' and 'goToClient' in a transaction) .

@subtractFromAccount(sourceAccountNo, amount)
@addToAccount(destinationAccountNo, amount) 
var transactionDeadline = @getTransactionDeadline()

// Go back to the client.
@goToClient()

// Handle the results on the client.
@setTransactionDeadline(transactionDeadline)
";
            var sources  = Shovel.Api.MakeSources("request.sho", program);
            var bytecode = Shovel.Api.GetBytecode(sources);

            // Run on the client to fill in request data.
            Shovel.Vm.Vm vm = null;
            TimeIt("client - initialization", () => {
                vm = Shovel.Api.RunVm(bytecode, sources, Udps());
            }
                   );
            var serializedBytecode = Shovel.Api.SerializeBytecode(bytecode);
            var serializedState    = Shovel.Api.SerializeVmState(vm);

            byte[] requestBytes = null;
            using (var ms = new MemoryStream()) {
                byte[] bytes = new byte[4];

                bytes = BitConverter.GetBytes(serializedBytecode.Length);
                ms.Write(bytes, 0, bytes.Length);

                var sourceBytes = Encoding.UTF8.GetBytes(program);

                bytes = BitConverter.GetBytes(sourceBytes.Length);
                ms.Write(bytes, 0, bytes.Length);

                bytes = BitConverter.GetBytes(serializedState.Length);
                ms.Write(bytes, 0, bytes.Length);

                ms.Write(serializedBytecode, 0, serializedBytecode.Length);
                ms.Write(sourceBytes, 0, sourceBytes.Length);
                ms.Write(serializedState, 0, serializedState.Length);

                requestBytes = ms.ToArray();
            }
            byte[] responseBytes = null;
            // Send the Shovel process to the server.
            TimeIt("server", () => {
                using (var wc = new WebClient()) {
                    responseBytes = wc.UploadData("http://localhost:8080/", requestBytes);
                }
            }
                   );
            // Extract the new state of the Shovel process from the HTTP response.
            byte[] serializedServerState = null;
            using (var ms = new MemoryStream(responseBytes)) {
                byte[] bytes = new byte[4];

                ms.Read(bytes, 0, 4);
                int serverStateLength = BitConverter.ToInt32(bytes, 0);

                serializedServerState = new byte[serverStateLength];
                ms.Read(serializedServerState, 0, serializedServerState.Length);
            }
            // Run again on the client to extract the data from the program.
            TimeIt("client - postprocess", () => {
                Shovel.Api.RunVm(bytecode, sources, Udps(), serializedServerState);
            }
                   );
        }
コード例 #3
0
ファイル: Api.cs プロジェクト: ichaos/Shovel
 public static ShovelException VmProgrammingError(Shovel.Vm.Vm vm)
 {
     return(vm.ProgrammingError);
 }
コード例 #4
0
ファイル: Main.cs プロジェクト: richardy2012/Shovel
        public static void Main(string[] args)
        {
            if (!HttpListener.IsSupported)
            {
                Console.WriteLine("HttpListener not available.");
                Environment.Exit(-1);
            }
            HttpListener hl = new HttpListener();

            hl.Prefixes.Add("http://localhost:8080/");
            hl.Start();
            while (hl.IsListening)
            {
                var ctx = hl.GetContext();

                Console.WriteLine("Serving a request ({0}).", ctx.Request.Url.AbsolutePath);

                if (ctx.Request.Url.AbsolutePath == "/")
                {
                    byte[] bytes = new byte[4];

                    byte[] state    = null;
                    string program  = null;
                    byte[] bytecode = null;

                    TimeIt("read request", () => {
                        ctx.Request.InputStream.Read(bytes, 0, bytes.Length);
                        int bytecodeLength = BitConverter.ToInt32(bytes, 0);

                        ctx.Request.InputStream.Read(bytes, 0, bytes.Length);
                        int sourcesLength = BitConverter.ToInt32(bytes, 0);

                        ctx.Request.InputStream.Read(bytes, 0, bytes.Length);
                        int stateLength = BitConverter.ToInt32(bytes, 0);

                        bytecode = new byte[bytecodeLength];
                        ctx.Request.InputStream.Read(bytecode, 0, bytecode.Length);

                        byte[] sourceBytes = new byte[sourcesLength];
                        ctx.Request.InputStream.Read(sourceBytes, 0, sourceBytes.Length);
                        program = Encoding.UTF8.GetString(sourceBytes);

                        state = new byte[stateLength];
                        ctx.Request.InputStream.Read(state, 0, state.Length);
                    }
                           );

                    // To execute the ShovelScript code between
                    // @goToServer and @goToClient in a DB transaction,
                    // just wrap this call in a DB transaction.

                    Shovel.Vm.Vm vm = null;
                    TimeIt("server", () => {
                        vm = Shovel.Api.RunVm(
                            Shovel.Api.DeserializeBytecode(bytecode),
                            Shovel.Api.MakeSources("request.sho", program),
                            Udps(),
                            state);
                    }
                           );

                    // In a real application, we should check the values returned by
                    // Shovel.Api.VmProgrammingError and Shovel.Api.VmUserDefinedPrimitiveError
                    // and return something else based on the presence/absence of errors.

                    // In a normal context, you must set quotas for RAM and CPU when calling RunVm (so a single
                    // broken/malicious request doesn't bring down the whole server). This is not
                    // done here to keep things simple.

                    // This is accomplished using the RunVm 'totalTicksQuota' and 'usedCellsQuota' parameters.

                    // Using 'ticksUntilNextNapQuota' should also be used to protect against infinite loops.

                    byte[] stateAfter = null;
                    TimeIt("serialize state", () => {
                        stateAfter = Shovel.Api.SerializeVmState(vm);
                    }
                           );

                    TimeIt("write response", () => {
                        bytes = BitConverter.GetBytes(stateAfter.Length);
                        ctx.Response.OutputStream.Write(bytes, 0, bytes.Length);
                        ctx.Response.OutputStream.Write(stateAfter, 0, stateAfter.Length);
                    }
                           );
                }
                ctx.Response.OutputStream.Close();

                Console.WriteLine("Finished serving request.");
            }
        }