From dc8a1d4356432cc414f3e2b66598b4fb325e1c0e Mon Sep 17 00:00:00 2001 From: "Peter J. Keleher" <keleher@cs.umd.edu> Date: Mon, 11 Sep 2023 14:02:40 -0400 Subject: [PATCH] auto --- p2.md | 130 ++++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 86 insertions(+), 44 deletions(-) diff --git a/p2.md b/p2.md index 8c7eafe..eb7ad4b 100644 --- a/p2.md +++ b/p2.md @@ -1,9 +1,12 @@ # Project 2: Remote Procedure Calls and Remote Servers **Due: Sept 24, 2023, 11:59:59 pm, v1** +## Big Picture + This project requires you to use gRPC to split your code from Project 1 into a command-line interface and a *blobserver*. You will also build a discrete *lockserver* that responds to gRPC lock and unlock requests. +the system. ## gRPC @@ -22,7 +25,7 @@ Download starter files from [here](http://triffid.cs.umd.edu/818/projects/p2.tgz For example, on a mac: ``` - brew install protobuf + brew install protobuf` protoc --version # at least 24.3 go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.28 @@ -74,14 +77,76 @@ Each of these locks should be implemented with `sync.RWMutex`, and acquire reque paths already locked with incompatible modes would result in the gRPC request being blocked until the situation changes. -## Details +## Details: gRPC protocol definition + +`pb/comm.proto` will define the object services that your servers will respond +to. I gave you the service definition, and the "message" definitions +for the `BlobPutRequest`. Define the others similarly. + +Then, compile the protocol w/ the `protoc` command in the comment. +This will create files `comm.pb.go` and `comm_grpc.pb.go`. The latter +defines the routines that use object *reflection* to generate +communication stubs that call the functions you write in your server. + +The service definition is: +``` +service Blob { + rpc Put (BlobPutRequest) returns (BlobPutReply) {} + rpc Get (BlobGetRequest) returns (BlobGetReply) {} + rpc List (BlobListRequest) returns (BlobListReply) {} + + rpc Lock (LockRequest) returns (LockReply) {} + rpc Unlock (UnlockRequest) returns (UnlockReply) {} +} +``` +You will need to define server routines corresponding to each of the +above. For example, the `put` command function will look like: +``` +func (s *GRPCserver) Put(ctx context.Context, in *pb.BlobPutRequest) (*pb.BlobPutReply, error) { + + .... + + return &pb.BlobPutReply{Sig: sig, ErrorString: ""}, nil +} +``` -- `pbc/comm.proto` defines the object services that your servers will respond -to. The starter files contain files `tool/main.go` for talking to the -blobserver, and `app.go` to exercise your lock server and show how an application could -use the interface. +Most of this stuff works seamlessly. One oddity is that when you start +up your server (in `server.go`), the actual startup is here: +``` + lis, err := net.Listen("tcp", ServerAddress) + if err != nil { + log.Fatalf("failed to listen: %v", err) + } + s := grpc.NewServer() + pb.RegisterBlobServer(s, &GRPCserver{}) -- The lock gRPC calls are made directly from the application level (see `app.go`) +``` +The `GRPCserver` is a placeholder structure that does not need to +define any properties or methods, except the `UnimplementedBlobServer` +method. From `blobstore/grpcServe.go` +``` +type GRPCserver struct { + pb.UnimplementedBlobServer +} +``` + +## Details: Locks + +Implement the locks using `Sync.RWMutex` from the standard +library. The `path` used to choose which lock to lock/unlock is an +arbitrary string, and *each path must have a distinct lock*. + +This means you need to create `RWMutex`'s at runtime. You can store them +in a map for easy lookup. Though I won't be testing high-speed +concurrent locks, your implementation should work w/ even when +multiple clients are trying to lock a path at the same time, and: +- the path hasn't been accessed before, so no lock is pre-existing +- you must ensure that only one `RWMutex` is create per lock (no + overwriting!). + +This is complicated by the fact that gRPC is multi-threaded; each incoming +request is given it's own server go-thread and runs concurrently with +all other requests ## Setup @@ -90,22 +155,21 @@ Download the starter files for this project [here](https://sedna.cs.umd.edu/818/ ## Command-line parameters +The server: ``` - go run cli.go [-d|-s <host:port>] (desc <sig>|get <sig> <destination>|put <source>|list|lock <path>|unlock <path>) - go run store.go [-d|-s <host:port>] + go run server.go [-d] [-s <host:port>] ``` -## Testing - -There are several moving parts here, though you won't be writing all that much code. *Test -parts separately* when possible: -- `blobget.go` will use the same gRPC definitions to interact with your blobserver as -your main fuse program. Use it list the contents of the database and to debug your gRPC -code. +The clients: +``` + go run blob.go [-d] [-s <host:port>] (desc <sig>|get <sig> <destination>|put <source>|list|lock <path>|unlock <path>) + go run lock.go [-d] [-s <host:port>] (lock <path>|rlock <path>|unlock <path>|runlock <path>) +``` -- `app.go` will use the same gRPC definitions as your lock server. I will be using it to -test your lockserver; you should too. +## Testing +The testscript from before is a good place to start, but you also need +locking behavior identical as shown in the video. ## Notes - Use the `context` to set RPC timeouts to 60 seconds. @@ -113,34 +177,12 @@ test your lockserver; you should too. ## Grading I will assign grades vaguely as follow: -- 50 pts - blobserver - - `redis` test - - examine contents of leveldb and server workings w/ `blobget.go` -- 50 pts - lockserver - - I'll pass it various paths and verify that the correct locks are acquired, that gRPCs - are blocked until conditions are appropriate, and releases are correct. A release from - replica *i* should not unblock a lock held only by repica *j*. - -## Files - -This repository -contains the following files: -- `main.go` - Scaffolding for P3, which references files in subdirs `dfs`, `pbc`, and `pbl`. -- `blobget.go` - retrieves data corresponding to specific signature, name (such as - 'head'), or pathname from your blobserver. Can also be used to print out all keys in the object store. -- `app.go` tester for your lockserver. -- `blob/pbc.proto` - definition of protobuf formats and services for blobserver -- `lock/pbl.proto` - definition of protobuf formats and services for lockserver - -## Submit +- 70 pts - distributing the blobserver +- 30 pts - lockserver -Submit as follows (substituting your *real* directoryid for `<your dirid>`): -``` - cd ~/go/src/818fall18/ - tar cvfz p3.tgz p3 -``` -and upload to [myelms](https://myelms.umd.edu/courses/1247011/assignments/4738791). +## Submit +Submit by copying into your distro and pushing to gitlab. -- GitLab