-
Notifications
You must be signed in to change notification settings - Fork 77
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
FileManager #112
FileManager #112
Conversation
package main | ||
|
||
import ( | ||
"flag" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please use "github.com/namsral/flag" (a drop in replacement of "flag") instead of "flag", since the former can parse env variable as input.
Please see this discussion: PaddlePaddle/Paddle#2245 (comment)
Usage of "github.com/namsral/flag" see: https://github.com/PaddlePaddle/Paddle/blob/develop/paddle/go/cmd/pserver/pserver.go#L9
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@helinwang @typhoonzero github.com/golang/glog
里边判断了
679 if !flag.Parsed() {
680 os.Stderr.Write([]byte("ERROR: logging before flag.Parse: "))
681 os.Stderr.Write(data)
682 }
而它用的是go原生的flag
,所以用了github.com/namsral/flag
,每一行打印中都会出现类似
ERROR: logging before flag.Parse: I0531 11:34:47.868818 3294 main.go:21]
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
鉴于需要使用glog
的level日志的功能,同时flag
的功能已经足够用了。先用flag
。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok. It's fine as long as we don't need to parse environment variable for file server.
go/cmd/pfsserver/main.go
Outdated
|
||
router := pfsserver.NewRouter() | ||
|
||
portPtr := flag.Int("port", 8080, "listen port") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
port
would suffice. Go prefer short variable names. See: https://github.com/golang/go/wiki/CodeReviewComments#variable-names
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
go/filemanager/pfsmod/chunk.go
Outdated
"strconv" | ||
) | ||
|
||
//ChunkCmd structure |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The code next line already shows it's a struct, I think we need a more descriptive comment.
Also, please leave a space after "//": // comment
.
Please see: https://github.com/golang/go/wiki/CodeReviewComments#comment-sentences
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
go/filemanager/pfsmod/chunk.go
Outdated
|
||
//ToJSON encodes chunkcmd to json string | ||
func (p *ChunkCmd) ToJSON() ([]byte, error) { | ||
return nil, nil |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why it's returning nil, nil
, is it not implemented? If so, do you plan to implement it later? If so, maybe panic("not implemented")
is better.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
go/filemanager/pfsmod/command.go
Outdated
|
||
const ( | ||
//DefaultMultiPartBoundary is the default multipart form boudary | ||
DefaultMultiPartBoundary = "8d7b0e5709d756e21e971ff4d9ac3b20" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's only used by package pfsserver
, why not put it there?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
这个是paddlecloud package
和pfsserver package
都用到了,所以放到了pfsmod package
中
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
明白了。
go/filemanager/pfsmod/chunk.go
Outdated
//NewChunkCmdFromURLParam get a ChunkCmd structure | ||
// path example: | ||
// path=/pfs/datacenter1/1.txt&offset=4096&chunksize=4096 | ||
func NewChunkCmdFromURLParam(path string) (*ChunkCmd, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
NewChunkCmdFromURLParam
is a very long name, maybe ParseChunkCmd
is a better name?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
go/filemanager/pfsmod/chunk.go
Outdated
|
||
//Run function runs a ChunkCmd | ||
func (p *ChunkCmd) Run() (interface{}, error) { | ||
return nil, nil |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why it's returning nil, nil
, is it not implemented? If so, do you plan to implement it later? If so, maybe panic("not implemented")
is better.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
go/filemanager/pfsmod/chunk.go
Outdated
) | ||
|
||
//ChunkCmd structure | ||
type ChunkCmd struct { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we need a comment that describe what is ChunkCmd, I am confused why there is "cmd", from the definition, I can not see what "cmd" does?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
go/filemanager/pfsmod/ls.go
Outdated
cmd := LsCmd{} | ||
|
||
m, err := url.ParseQuery(path) | ||
if err != nil || |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if err != nil
just indicate the parsing failed, it's not "not enough arguments", maybe we should use a different StatusText for it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
go/filemanager/pfsmod/chunk.go
Outdated
return nil, errors.New(StatusText(StatusJSONErr)) | ||
} | ||
|
||
//var err error |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This line should be removed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
go/filemanager/pfsmod/status.go
Outdated
// need a custome error type? | ||
|
||
const ( | ||
StatusFileNotFound = 520 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
好像只有在提取statusText的时候采用到了error code,还有其他时候需要用error code吗?
如果是这样的话,需要把error code暴露出package之外吗,以及,有必要有error code这个东西吗?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
这个我也在犹豫,是否应该定义一个自己的error类型,errno用来判定,errtext用来提示。所以上边写了一个注释:need a custom error type?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
感觉直接用HTTP的状态码也是可以的。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
这一版先用text。等我找到更好的办法的时候再重构一下。
go/filemanager/pfsmod/chunkmeta.go
Outdated
break | ||
} | ||
|
||
//log.Println(n) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please no commented out code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
go/filemanager/pfsmod/chunkmeta.go
Outdated
defaultMaxChunkSize = 4 * 1024 * 1024 | ||
defaultMinChunkSize = 4 * 1024 | ||
//DefaultChunkSize is the default chunk's size | ||
DefaultChunkSize = 2 * 1024 * 1024 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
DefaultChunkSize
只被另一个package用到,是不是该放在另一个package里面?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
哦。有道理。我本来是想把关于同一个主题的都放到一个文件中。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
go/filemanager/pfsmod/resp.go
Outdated
package pfsmod | ||
|
||
//JSONResponse is the common response from server | ||
type JSONResponse struct { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The result
field type of all response struct is interface{}
in Go, so maybe we can only need one struct named:
type Response struct {
Err string `json:"err"`,
Result interface{} `json:"result"`
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
有道理。只是这个parse的时候会出错。可以把resp.go的内容重新分配了一下,删除了这个文件。
go/filemanager/pfsmod/status.go
Outdated
// need a custome error type? | ||
|
||
const ( | ||
StatusFileNotFound = 520 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
感觉直接用HTTP的状态码也是可以的。
go/filemanager/pfsmod/chunk.go
Outdated
type ChunkCmd struct { | ||
Path string | ||
Offset int64 | ||
ChunkSize int64 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ChunkSize
may be a global const or read from some command-line arguments or config file.
Else if you intend to save the size of current chunk, it should be named size
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
go/filemanager/pfsmod/chunk.go
Outdated
@@ -0,0 +1,118 @@ | |||
package pfsmod |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This package name filemanager/pfsmod
seems confusing. You should name it like pfs/pfscommands
or pfs/pfsmodules
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
go/filemanager/pfsmod/chunk.go
Outdated
return err | ||
} | ||
|
||
//SaveChunkData save data from r |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SaveChunkData save data from r
=> SaveChunkData save data from io.Reader
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
go/filemanager/pfsmod/chunk.go
Outdated
return &cmd, nil | ||
} | ||
|
||
//LoadChunkData loads a specified chunk to w |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LoadChunkData loads a specified chunk to w
=> LoadChunkData loads a specified chunk to io.Writer
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
go/filemanager/pfsmod/chunkmeta.go
Outdated
@@ -0,0 +1,221 @@ | |||
package pfsmod |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
chunkmeta
definations should also add to design doc: https://github.com/PaddlePaddle/Paddle/tree/develop/doc/design/file_manager
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
这个后续补上。
go/cmd/pfsserver/main.go
Outdated
) | ||
|
||
func main() { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nitpicking here, I know new line can separate regions of code of different functionalities, but a new line at the beginning of a function does not seem necessary?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
习惯于大括号在第二行居左了。
go/cmd/pfsserver/main.go
Outdated
func main() { | ||
|
||
port := flag.Int("port", 8080, "port of server") | ||
ip := flag.String("ip", "0.0.0.0", "ip of server") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just curious, when will the ip of server necessary? I usually do ":8080" rather than "0.0.0.0:8080" so that I don't need to specify the ip.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ip
port
都可以不用指定。中间的是他们的默认值。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Listening on an IP address is always useful, ":8080" is the same as "0.0.0.0:8080". When we need to bind TCP server to the specified network(in a LAN or VLAN or VPC), we need to specify the IP of the network card.
go/filemanager/pfsmodules/chunk.go
Outdated
log "github.com/golang/glog" | ||
) | ||
|
||
// Chunk respresents a chunk info |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please see https://github.com/golang/go/wiki/CodeReviewComments#comment-sentences , comments should be a full sentence. (end with a period ".")
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
go/filemanager/pfsmodules/status.go
Outdated
// need a custom error type? | ||
|
||
const ( | ||
StatusFileNotFound = "no such file or directory" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does these errors needs to be public (visible outside of the package)?
Typically errors are used:
var ErrFileNotFound = errors.New("no such file or directory")
See: https://golang.org/src/io/io.go
But most of the time error do not need to be exported, since people who use the library does not need to differentiate between difference errors.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
error
类型没法序列化到JSON以及从JSON中反序列化。- 确实需要区分错误:如文件不存在。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@gongweibao 我查了一下,貌似现在的code并没有把这些status序列化到json?如果需要序列化的话,err.Error()
是不是更符合Go idiom?
go/filemanager/pfsmodules/chunk.go
Outdated
} | ||
|
||
writen, err := io.CopyN(w, f, p.Size) | ||
log.V(2).Infof("writen:%d\n", writen) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought this function loads data, why here says "written"? Maybe "loaded" is more appropriate?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
go/filemanager/pfsmodules/command.go
Outdated
|
||
const ( | ||
// DefaultMultiPartBoundary is the default multipart form boudary | ||
DefaultMultiPartBoundary = "8d7b0e5709d756e21e971ff4d9ac3b20" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think in general const block can be put together:
const (
DefaultMultiPartBoundary = "8d7b0e5709d756e21e971ff4d9ac3b20"
MaxJSONRequestSize = 2048
If you want to write them separately, you can do:
const DefaultMultiPartBoundary = "8d7b0e5709d756e21e971ff4d9ac3b20"
const MaxJSONRequestSize = 2048
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
go/filemanager/pfsserver/handler.go
Outdated
func writeJSONResponse(w http.ResponseWriter, | ||
req string, | ||
httpStatus int, | ||
resp *response) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe pass by value is better resp response
. Please see https://github.com/golang/go/wiki/CodeReviewComments#pass-values
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
go/filemanager/pfsserver/handler.go
Outdated
|
||
// PostFilesHandler processes files' POST request | ||
func PostFilesHandler(w http.ResponseWriter, r *http.Request) { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe this empty line is not necessary.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
go/filemanager/pfsserver/handler.go
Outdated
result, err := cmd.Run() | ||
if err != nil { | ||
resp.Err = err.Error() | ||
resp.Results = result |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't result
invalid when err != nil
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
go/filemanager/pfsmodules/ls.go
Outdated
|
||
// Run functions runs LsCmd and return LsResult and error if any happened | ||
func (p *LsCmd) Run() (interface{}, error) { | ||
results := make([]LsResult, 0, 100) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why the capacity is set to 100? Please do not optimize at the cost of code clarity if it's not identified as a bottleneck.
var results []LsResult
is probably more appropriate. (calling append
/ len
using a nil
slice is fine)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
go/paddlecloud/pfssubmit.go
Outdated
return nil, err | ||
} | ||
|
||
url := fmt.Sprintf("%s:%d/api/v1/files", s.config.ActiveConfig.Endpoint, s.port) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need to add s.port
. Endpoint
already contains it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
go/paddlecloud/pfssubmit.go
Outdated
return &pfsSubmitter{ | ||
config: config, | ||
client: client, | ||
port: 8080, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Port is hard coded
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
go/paddlecloud/pfssubmit.go
Outdated
@@ -0,0 +1,246 @@ | |||
package paddlecloud |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PFS operations are not "submits", so we don't need a pfsSubmitter
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
submitter
其实是提交命令的意思。接口是面向Command interface
的。这个接口部分我觉得可以保留。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
还是有点牵强。一般会说submit a job, submit a task,run a command. 如果都是HTTP请求,直接调用Get, Post函数即可,可以省掉这个struct
go/paddlecloud/pfssubmit.go
Outdated
} | ||
|
||
// PostFiles implements files' POST method. | ||
func (s *pfsSubmitter) PostFiles(cmd pfsmod.Command) ([]byte, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can put HTTP client operations in restclient.go
, I'll do some refactor to restclient.go
so it is more flexible.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK。pfssubmitter
里边可以调用这几个GetCall
和PostCall
等几个函数。
) | ||
|
||
type response struct { | ||
Err string `json:"err"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need to use a same form of general response, like:
{ "code": 0, "msg": "OK or Error", "items": {...}}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
这个response就是一个general response
。Results
是一个interface
,不赋值的时候就是nil
。JSON解析没有问题,而且这个时候客户端是不需要知道具体的Results是什么。
code这个思路不太可行。golang里边都是error
对象,是没有error code
的。如果要传error code
就要在所有return err
的地方做一个转换
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
是说需要一个规范性质的,描述所有的REST response json的格式。包括pfs和submit等API。如果没有code 也可以,是需要一个统一的返回格式。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
可以考虑:
type responseStatus struct {
Err string `json:"msg"`
}
type response {
responseStatus
Results interface{} `json:"results"`
}
// ...
type chunkMetaResponse struct {
responseStatus
Results []pfsmod.ChunkMeta `json:"results"`
}
这样的好处是,可以确保所有的HTTP Response都有固定的status格式。方便client实现统一的parsing logic(client需要parse了status再决定下一步干什么,是报错还是继续执行)。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
helin,这个没有太理解。Err
放到一个结构体中和单独出来的区别是?
go/filemanager/pfsmodules/ls.go
Outdated
} | ||
|
||
// CloudCheck checks the conditions when running on cloud. | ||
func (p *LsCmd) CloudCheck() error { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
CloudCheck()
and LocalCheck()
seems the same at mkdir.go
, rm.go
etc. with slitly differences, can we make it more simpler?
By the way, I don't quite understand what does "checks the conditions when running on cloud." means.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- 命令面向用户的基本设定都是在Cloud端运行,所以按照道理是不需要
LocalCheck
的 - 不过,像
Ls
这样的命令,cp
用到了本地其本地运行的结果,所以把命令抽象为interface以后,加入了LocalCheck
和CloudCheck
,以便 - 在
Local
只需要检查参数的个数等,而在Cloud上
需要检查用户的对目录的权限。其实是不一样的。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
我的理解:
- 检查参数一般都叫作:
validate
,如果只是检查参数合法性,是要实现validate函数,比如检查dest是否是/pfs
开始 - 服务端检查用户对目录的权限,只需要比较认证后的
username == path[3]
即可
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
可以缩短。
go/filemanager/pfsmodules/command.go
Outdated
} | ||
|
||
// Close closes c and log it. | ||
func Close(c io.Closer) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Close should not be visible from outside of the package.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
我的思路是这样的:有两个package中用到这个函数,为了防止两个包相互调用,所以定义了一个pfsmodules作为中间的公共package,然后把公共函数放到了它里边。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
这种简单的函数,就直接放在package内吧。另外,防止相互调用往往会用interface(好像挺少因为这个再去加一个新的package,创建新package的目的可能是为了模块化,而不是解决循环依赖),比如:
package a
import "b"
var c = b.Foo()
type T int
func (t T) Bar() {
}
package b
type interface Bar {
Bar()
}
// can't import "a" and use a.T as an argument, using a interface.
func Baz(b Bar) {
}
func Foo() {
}
package main
func main() {
b.Baz(a.T(0))
}
往往必须有循环依赖的时候还是比较少的。
// CloudCheck checks the conditions when running on cloud. | ||
func (p *ChunkMetaCmd) CloudCheck() error { | ||
if !IsCloudPath(p.FilePath) { | ||
return errors.New(StatusShouldBePfsPath + ": p.FilePath") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe should be return errors.New(StatusShouldBePfsPath + ":" + p.FilePath)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
惭愧,搞错了。
Done
return nil, err | ||
} | ||
|
||
metas := make([]ChunkMeta, 0, fi.Size()/len+1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry I don't understand why there is a +1
in fi.Size()/len+1
, I thought (fi.Size() + len - 1)/len
is the ceil(fi.Size()/len)
.
Anyway, I think var metas []ChunkMeta
is more fool proof, and easy to read. The optimization here will not have any visible impact to the performance. We should choose code clarity rather than performance, unless performance is a bottleneck.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
go/filemanager/pfsmodules/cp.go
Outdated
if flag.Name == "v" { | ||
cmd.V, err = strconv.ParseBool(flag.Value.String()) | ||
if err != nil { | ||
panic(err) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
https://github.com/golang/go/wiki/CodeReviewComments#dont-panic
I think in general no code should panic besides maybe it's ok if code in package main
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Visit
这个函数没有返回值可以供使用。
用goto
跳出来?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe:
var err error
f.Visit(func(flag *flag.Flag) {
if err != nil {
return
}
if flag.Name == "v" {
cmd.V, err = strconv.ParseBool(flag.Value.String())
}
})
if err != nil {
return nil, err
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
多谢helin。Done。
} | ||
|
||
// NewLsCmdFromFlag returen a new LsCmd. | ||
func NewLsCmdFromFlag(f *flag.FlagSet) (*LsCmd, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Need test case, it's fine to have it in another PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK,我记录了。
go/filemanager/pfsmodules/stat.go
Outdated
|
||
return &LsResult{ | ||
Path: p.Path, | ||
ModTime: fi.ModTime().Format("2006-01-02 15:04:05"), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not use info.ModTime().UnixNano()
, which is more precise. We only need string when print out the data.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
) | ||
|
||
type response struct { | ||
Err string `json:"err"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
可以考虑:
type responseStatus struct {
Err string `json:"msg"`
}
type response {
responseStatus
Results interface{} `json:"results"`
}
// ...
type chunkMetaResponse struct {
responseStatus
Results []pfsmod.ChunkMeta `json:"results"`
}
这样的好处是,可以确保所有的HTTP Response都有固定的status格式。方便client实现统一的parsing logic(client需要parse了status再决定下一步干什么,是报错还是继续执行)。
} | ||
|
||
// Execute runs a MkdirCommand. | ||
func (p *MkdirCommand) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{}) subcommands.ExitStatus { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the purpose for context.Context
, is it for cancellation, if so, why it's not implemented?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
这个是subcommands package
里边Command interface
要求实现的。
go/paddlecloud/pfssubmit.go
Outdated
func newPfsCmdSubmitter(configFile string) *pfsSubmitter { | ||
// TODO | ||
/*https | ||
pair, e := tls.LoadX509KeyPair(config.ActiveConfig.Usercert, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please no commented out code. You can put the code on Evernote :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK.
go/paddlecloud/pfssubmit.go
Outdated
|
||
log.V(1).Infof("%#v\n", config) | ||
|
||
//http |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This comment does not provide any information.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
With this PR, the user should configure two kinds of authentication: basic auth means username && password and tls key files at the same time, It look so confusing.
|
// need a custom error type? | ||
|
||
const ( | ||
StatusFileNotFound = "no such file or directory" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am still not convinced that we need these string constants, and these string constant need to be visible outside of the package.
Can you take a look at : #112 (comment)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After offline discussion with @gongweibao , it's used by the client to compare these string with the error message returned from the server over HTTP.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
多谢helin.
} | ||
|
||
// ToURLParam encodes ChunkMetaCmd to URL encoding string. | ||
func (p *ChunkMetaCmd) ToURLParam() url.Values { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These code are repetitive, a good candidate for automatically generating them. See: https://blog.golang.org/generate
Not required, just want to let you know :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
棒。我正要模仿JSON的Marshal函数自己搞一个那。多谢helin。
后续改进它。
go/paddlecloud/download.go
Outdated
} | ||
|
||
// DownloadFile downloads src to dst. If dst does not exists, create it with srcFileSize. | ||
func DownloadFile(src string, srcFileSize int64, dst string) error { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this necessary to be visible outside of the package?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
go/paddlecloud/download.go
Outdated
} | ||
|
||
// Download function downloads src to dst. | ||
func Download(src, dst string) error { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this necessary to be visible outside of the package?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM after the two function being visible outside the package comment.
Results interface{} `json:"results"` | ||
} | ||
|
||
func makeRequest(uri string, method string, body io.Reader, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can call this function from package paddlecloud
instead of copy again.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
会引入很多不必要的用来,比如全局变量config
。
或者把restclient
放到公共的地方去。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
这个merge进去以后,下个版本继续改正。不然改动太大,容易出问题。
return req, nil | ||
} | ||
|
||
func getResponse(req *http.Request) ([]byte, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can call this function from package paddlecloud instead of copy again.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
会引入很多不必要的用来,比如全局变量config。
或者把restclient放到公共的地方去
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
这个merge进去以后,下个版本继续改正。不然改动太大,容易出问题。
func getUserName(uri string, token string) (string, error) { | ||
authHeader := make(map[string]string) | ||
authHeader["Authorization"] = "Token " + token | ||
req, err := makeRequest(uri, "GET", nil, "", nil, authHeader) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can call makeTokenRequest
directly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
会引入很多不必要的用来,比如全局变量config。
或者把restclient放到公共的地方去
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
这个merge进去以后,下个版本继续改正。不然改动太大,容易出问题。
go/filemanager/pfsserver/handler.go
Outdated
return "", err | ||
} | ||
|
||
log.V(4).Infoln("before getResponse") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This debug log maybe not needed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
go/filemanager/pfsserver/handler.go
Outdated
func GetChunkHandler(w http.ResponseWriter, r *http.Request) { | ||
log.V(1).Infof("begin proc GetChunkHandler") | ||
|
||
cmd, err := pfsmod.ParseChunk(r.URL.RawQuery) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ParseChunk
returns a *Chunk
type but the variable is cmd
. Previous review I commented ChunkCmd
is confusing, so we changed ChunkCmd
to Chunk
. But when using it we still treat it as a Cmd
.
Don't know how to do.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
} | ||
|
||
switch method { | ||
case "rm": |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why "rm", "touch", "mkdir", shares the same URL route and use the same handler?
In REST, resource removal methods should use DELETE
HTTP method.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
switch method { | ||
case "rm": | ||
rmHandler(w, body, r.Header) | ||
case "touch": |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
touchHandler
can reuse PostChunkHandler
to create an empty file?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
语义不一样。一个是创建文件,一个是上传Chunk。
touch
创建的是sized
的文件。
go/filemanager/pfsmodules/command.go
Outdated
|
||
// Command is a interface of all commands. | ||
type Command interface { | ||
ToURLParam() url.Values |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Better to add comments for each interface usages? like
// ToURLParam convert the current pfs command to a url.Values struct which will be used by pfs server and client.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
go/filemanager/pfsmodules/command.go
Outdated
|
||
// CheckUser checks if a user has authority to access a path. | ||
func checkUser(path string, user string) error { | ||
// TODO |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this function still a TODO?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
@@ -0,0 +1,131 @@ | |||
package paddlecloud |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we merge content of these files(pfscp.go
, pfsls.go
, pfsmkdir.go
, pfsrm.go
) to filemanager/pfsmodules/*.go
?
For example, in ls.go
:
// LsCmd means LsCommand structure.
type LsCmd struct {
Method string
R bool
Args []string
}
// for subcommand
func (*LsCmd) Name() string { return "ls" }
func (*LsCommand) Synopsis() string { return "List files on PaddlePaddle Cloud" }
...
// original command implementations
func (p *LsCmd) ToURLParam() url.Values {
...
In cmd/paddlecloud/paddlecloud.go
:
subcommands.Register(&pfsmod.LsCmd{}, "")
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
这个merge进去以后,下个版本继续改正。不然改动太大,容易出问题。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
No description provided.