| giolekva | 53bcdf4 | 2020-03-25 23:30:49 +0400 | [diff] [blame] | 1 | package controller |
| Giorgi Lekveishvili | b8f089f | 2020-03-18 23:28:12 +0400 | [diff] [blame] | 2 | |
| giolekva | c5126d9 | 2020-03-21 16:39:56 +0400 | [diff] [blame] | 3 | import ( |
| 4 | "context" |
| 5 | "log" |
| 6 | "math/rand" |
| Giorgi Lekveishvili | b8f089f | 2020-03-18 23:28:12 +0400 | [diff] [blame] | 7 | |
| giolekva | c5126d9 | 2020-03-21 16:39:56 +0400 | [diff] [blame] | 8 | "github.com/google/uuid" |
| giolekva | 1f6577a | 2020-03-25 12:53:06 +0400 | [diff] [blame] | 9 | "google.golang.org/grpc" |
| Giorgi Lekveishvili | b8f089f | 2020-03-18 23:28:12 +0400 | [diff] [blame] | 10 | |
| giolekva | b47be77 | 2020-04-11 15:23:37 +0400 | [diff] [blame^] | 11 | "github.com/giolekva/pcloud/pfs/api" |
| giolekva | c5126d9 | 2020-03-21 16:39:56 +0400 | [diff] [blame] | 12 | ) |
| Giorgi Lekveishvili | b8f089f | 2020-03-18 23:28:12 +0400 | [diff] [blame] | 13 | |
| 14 | type chunkServers struct { |
| 15 | address string |
| 16 | } |
| 17 | |
| 18 | type BlobStatus int |
| 19 | |
| 20 | const ( |
| 21 | NEW BlobStatus = iota |
| 22 | ) |
| 23 | |
| 24 | type ChunkStatus int |
| 25 | |
| 26 | const ( |
| 27 | ASSIGNED ChunkStatus = iota |
| 28 | STORED |
| 29 | ) |
| 30 | |
| 31 | type chunkReplica struct { |
| 32 | chunkServer string |
| 33 | status ChunkStatus |
| 34 | } |
| 35 | |
| 36 | type chunk struct { |
| 37 | id string |
| 38 | replica []chunkReplica |
| 39 | } |
| 40 | |
| 41 | type blob struct { |
| 42 | id string |
| 43 | status BlobStatus |
| 44 | chunks []chunk |
| 45 | } |
| 46 | |
| 47 | type MasterServer struct { |
| giolekva | 1f6577a | 2020-03-25 12:53:06 +0400 | [diff] [blame] | 48 | chunkServers []*chunkServer |
| Giorgi Lekveishvili | b8f089f | 2020-03-18 23:28:12 +0400 | [diff] [blame] | 49 | blobs []*blob |
| 50 | } |
| 51 | |
| 52 | func NewMasterServer() *MasterServer { |
| 53 | return &MasterServer{} |
| 54 | } |
| 55 | |
| 56 | func (s *MasterServer) AddChunkServer( |
| 57 | ctx context.Context, |
| giolekva | 1f6577a | 2020-03-25 12:53:06 +0400 | [diff] [blame] | 58 | req *api.AddChunkServerRequest) (*api.AddChunkServerResponse, error) { |
| 59 | s.chunkServers = append(s.chunkServers, &chunkServer{ |
| 60 | address: req.Address, |
| 61 | status: Healthy}) |
| 62 | log.Printf("Registered Chunk server: %s", req.Address) |
| Giorgi Lekveishvili | b8f089f | 2020-03-18 23:28:12 +0400 | [diff] [blame] | 63 | return &api.AddChunkServerResponse{}, nil |
| 64 | } |
| 65 | |
| 66 | func (s *MasterServer) CreateBlob( |
| 67 | ctx context.Context, |
| giolekva | 1f6577a | 2020-03-25 12:53:06 +0400 | [diff] [blame] | 68 | req *api.CreateBlobRequest) (*api.CreateBlobResponse, error) { |
| 69 | if int(req.NumReplicas) > len(s.chunkServers) { |
| Giorgi Lekveishvili | b8f089f | 2020-03-18 23:28:12 +0400 | [diff] [blame] | 70 | return nil, nil |
| 71 | } |
| 72 | resp := api.CreateBlobResponse{ |
| 73 | BlobId: uuid.New().String(), |
| 74 | Chunk: []*api.ChunkStorageMetadata{ |
| 75 | {ChunkId: uuid.New().String()}, |
| 76 | }} |
| giolekva | 1f6577a | 2020-03-25 12:53:06 +0400 | [diff] [blame] | 77 | assigned := 0 |
| 78 | chunkId := resp.Chunk[0].ChunkId |
| 79 | for i := range rand.Perm(len(s.chunkServers)) { |
| 80 | if assigned == int(req.NumReplicas) { |
| 81 | break |
| 82 | } |
| 83 | address := s.chunkServers[i].address |
| 84 | log.Printf(address) |
| 85 | var opts []grpc.DialOption |
| 86 | opts = append(opts, grpc.WithInsecure()) |
| 87 | opts = append(opts, grpc.WithBlock()) |
| 88 | conn, err := grpc.Dial(address, opts...) |
| 89 | if err != nil { |
| 90 | continue |
| 91 | } |
| 92 | defer conn.Close() |
| 93 | client := api.NewChunkStorageClient(conn) |
| 94 | createChunkReq := api.CreateChunkRequest{ |
| 95 | ChunkId: chunkId, |
| 96 | Size: req.SizeBytes} |
| 97 | if assigned == 0 { |
| 98 | createChunkReq.Role = api.ReplicaRole_PRIMARY |
| 99 | } else { |
| 100 | createChunkReq.Role = api.ReplicaRole_SECONDARY |
| 101 | createChunkReq.PrimaryAddress = resp.Chunk[0].Server[0] |
| 102 | } |
| 103 | _, err = client.CreateChunk(ctx, &createChunkReq) |
| 104 | if err == nil { |
| 105 | resp.Chunk[0].Server = append(resp.Chunk[0].Server, address) |
| 106 | assigned++ |
| 107 | } |
| Giorgi Lekveishvili | b8f089f | 2020-03-18 23:28:12 +0400 | [diff] [blame] | 108 | } |
| 109 | return &resp, nil |
| 110 | } |
| 111 | |
| 112 | func (s *MasterServer) GetBlobMetadata( |
| 113 | ctx context.Context, |
| giolekva | 1f6577a | 2020-03-25 12:53:06 +0400 | [diff] [blame] | 114 | req *api.GetBlobMetadataRequest) (*api.GetBlobMetadataResponse, error) { |
| Giorgi Lekveishvili | b8f089f | 2020-03-18 23:28:12 +0400 | [diff] [blame] | 115 | return nil, nil |
| 116 | } |