* * @brief: 在此文件描述符下创建一个文件,有三种类型目录,临时文件,文件 * @param: 实例号和路径名来源于文件描述符;文件类型;文件名称 * @return: 返回创建文件是否成功 * @notes: 对于返回值要先判断bool值再判断seq,bool为falseseq是没有意义的 */
(fd *FileDescriptor, Type int, filename string)
| 78 | * @notes: 对于返回值要先判断bool值再判断seq,bool为falseseq是没有意义的 |
| 79 | */ |
| 80 | func (ck *Clerk) Create(fd *FileDescriptor, Type int, filename string) (bool, *FileDescriptor){ |
| 81 | cnt := len(ck.servers) |
| 82 | |
| 83 | for { |
| 84 | args := &CreateArgs{PathName: fd.PathName, ClientID: ck.ClientID, SeqNo: ck.seq, |
| 85 | InstanceSeq: fd.InstanceSeq, FileType: Type, FileName: filename} |
| 86 | |
| 87 | reply := new(CreateReply) |
| 88 | |
| 89 | ck.leader %= cnt |
| 90 | |
| 91 | if atomic.LoadInt32(&((*ck.serversIsOk)[ck.leader])) == 0 { |
| 92 | ck.leader++ // 不能连接就切换 |
| 93 | continue |
| 94 | } |
| 95 | |
| 96 | replyArrival := make(chan bool, 1) |
| 97 | go func() { |
| 98 | err := ck.servers[ck.leader].Call("RaftKV.Create", args, reply) |
| 99 | flag := true |
| 100 | if err != nil { |
| 101 | log.Printf("ERROR : Create call error, Find the cause as soon as possible -> (%s).\n", err.Error()) |
| 102 | flag = false |
| 103 | } |
| 104 | replyArrival <- flag |
| 105 | }() |
| 106 | select { |
| 107 | case <-time.After(200 * time.Millisecond): // rpc timeout: 200ms |
| 108 | ck.leader++ |
| 109 | continue |
| 110 | case ok := <-replyArrival: |
| 111 | if ok && (reply.Err == OK) { |
| 112 | ck.seq++ |
| 113 | return true, &FileDescriptor{reply.CheckSum, reply.InstanceSeq, fd.PathName + "/" + filename} |
| 114 | } else if reply.Err == CreateError || reply.Err == Duplicate{ |
| 115 | // 对端打开文件失败 |
| 116 | log.Printf("INFO : Create (%s/%s) error -> [%s]\n", fd.PathName, filename, reply.Err) |
| 117 | ck.seq++ |
| 118 | return false, nil |
| 119 | } |
| 120 | ck.leader++ |
| 121 | } |
| 122 | } |
| 123 | } |
| 124 | |
| 125 | /* |
| 126 | * @param: opType为操作类型,可以为delete或者close |
no test coverage detected