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