diff options
Diffstat (limited to 'weed')
| -rw-r--r-- | weed/command/mount.go | 14 | ||||
| -rw-r--r-- | weed/command/mount_std.go | 5 | ||||
| -rw-r--r-- | weed/filer/filechunk_manifest.go | 2 | ||||
| -rw-r--r-- | weed/filer/reader_at.go | 18 | ||||
| -rw-r--r-- | weed/filer/stream.go | 2 | ||||
| -rw-r--r-- | weed/filesys/filehandle.go | 2 | ||||
| -rw-r--r-- | weed/server/filer_server_handlers_read_dir.go | 44 | ||||
| -rw-r--r-- | weed/server/filer_ui/templates.go | 19 |
8 files changed, 79 insertions, 27 deletions
diff --git a/weed/command/mount.go b/weed/command/mount.go index 7bf59cdc7..42a79bd1f 100644 --- a/weed/command/mount.go +++ b/weed/command/mount.go @@ -2,6 +2,7 @@ package command import ( "os" + "time" ) type MountOptions struct { @@ -25,9 +26,10 @@ type MountOptions struct { } var ( - mountOptions MountOptions - mountCpuProfile *string - mountMemProfile *string + mountOptions MountOptions + mountCpuProfile *string + mountMemProfile *string + mountReadRetryTime *time.Duration ) func init() { @@ -46,11 +48,13 @@ func init() { mountOptions.allowOthers = cmdMount.Flag.Bool("allowOthers", true, "allows other users to access the file system") mountOptions.umaskString = cmdMount.Flag.String("umask", "022", "octal umask, e.g., 022, 0111") mountOptions.nonempty = cmdMount.Flag.Bool("nonempty", false, "allows the mounting over a non-empty directory") - mountCpuProfile = cmdMount.Flag.String("cpuprofile", "", "cpu profile output file") - mountMemProfile = cmdMount.Flag.String("memprofile", "", "memory profile output file") mountOptions.outsideContainerClusterMode = cmdMount.Flag.Bool("outsideContainerClusterMode", false, "allows other users to access the file system") mountOptions.uidMap = cmdMount.Flag.String("map.uid", "", "map local uid to uid on filer, comma-separated <local_uid>:<filer_uid>") mountOptions.gidMap = cmdMount.Flag.String("map.gid", "", "map local gid to gid on filer, comma-separated <local_gid>:<filer_gid>") + + mountCpuProfile = cmdMount.Flag.String("cpuprofile", "", "cpu profile output file") + mountMemProfile = cmdMount.Flag.String("memprofile", "", "memory profile output file") + mountReadRetryTime = cmdMount.Flag.Duration("readRetryTime", 6*time.Second, "maximum read retry wait time") } var cmdMount = &Command{ diff --git a/weed/command/mount_std.go b/weed/command/mount_std.go index 14374eb5c..20d08314c 100644 --- a/weed/command/mount_std.go +++ b/weed/command/mount_std.go @@ -5,6 +5,7 @@ package command import ( "context" "fmt" + "github.com/chrislusf/seaweedfs/weed/filer" "github.com/chrislusf/seaweedfs/weed/filesys/meta_cache" "os" "os/user" @@ -29,6 +30,10 @@ import ( func runMount(cmd *Command, args []string) bool { grace.SetupProfiling(*mountCpuProfile, *mountMemProfile) + if *mountReadRetryTime < time.Second { + *mountReadRetryTime = time.Second + } + filer.ReadWaitTime = *mountReadRetryTime umask, umaskErr := strconv.ParseUint(*mountOptions.umaskString, 8, 64) if umaskErr != nil { diff --git a/weed/filer/filechunk_manifest.go b/weed/filer/filechunk_manifest.go index 9e53e008f..2df8a4bbf 100644 --- a/weed/filer/filechunk_manifest.go +++ b/weed/filer/filechunk_manifest.go @@ -98,7 +98,7 @@ func retriedFetchChunkData(urlStrings []string, cipherKey []byte, isGzipped bool var err error var buffer bytes.Buffer - for waitTime := time.Second; waitTime < 10*time.Second; waitTime += waitTime / 2 { + for waitTime := time.Second; waitTime < ReadWaitTime; waitTime += waitTime / 2 { for _, urlString := range urlStrings { err = util.ReadUrlAsStream(urlString, cipherKey, isGzipped, isFullChunk, offset, size, func(data []byte) { buffer.Write(data) diff --git a/weed/filer/reader_at.go b/weed/filer/reader_at.go index fa51df687..835d6cfc2 100644 --- a/weed/filer/reader_at.go +++ b/weed/filer/reader_at.go @@ -11,6 +11,11 @@ import ( "io" "math/rand" "sync" + "time" +) + +var ( + ReadWaitTime = 6 * time.Second ) type ChunkReadAt struct { @@ -37,7 +42,8 @@ func LookupFn(filerClient filer_pb.FilerClient) LookupFileIdFunctionType { vid := VolumeId(fileId) locations, found := vidCache[vid] - if !found { + waitTime := time.Second + for !found && waitTime < ReadWaitTime { // println("looking up volume", vid) err = filerClient.WithFilerClient(func(client filer_pb.SeaweedFilerClient) error { resp, err := client.LookupVolume(context.Background(), &filer_pb.LookupVolumeRequest{ @@ -56,6 +62,16 @@ func LookupFn(filerClient filer_pb.FilerClient) LookupFileIdFunctionType { return nil }) + if err == nil { + break + } + glog.V(1).Infof("wait for volume %s", vid) + time.Sleep(waitTime) + waitTime += waitTime / 2 + } + + if err != nil { + return nil, err } for _, loc := range locations.Locations { diff --git a/weed/filer/stream.go b/weed/filer/stream.go index f6e2a7643..a41aebe22 100644 --- a/weed/filer/stream.go +++ b/weed/filer/stream.go @@ -34,7 +34,7 @@ func StreamContent(masterClient *wdclient.MasterClient, w io.Writer, chunks []*f urlStrings := fileId2Url[chunkView.FileId] data, err := retriedFetchChunkData(urlStrings, chunkView.CipherKey, chunkView.IsGzipped, chunkView.IsFullChunk(), chunkView.Offset, int(chunkView.Size)) - if err == nil { + if err != nil { return err } w.Write(data) diff --git a/weed/filesys/filehandle.go b/weed/filesys/filehandle.go index 660bbf076..e1524f939 100644 --- a/weed/filesys/filehandle.go +++ b/weed/filesys/filehandle.go @@ -79,7 +79,7 @@ func (fh *FileHandle) Read(ctx context.Context, req *fuse.ReadRequest, resp *fus if err != nil { glog.Warningf("file handle read %s %d: %v", fh.f.fullpath(), totalRead, err) - return nil + return fuse.EIO } if totalRead > int64(len(buff)) { diff --git a/weed/server/filer_server_handlers_read_dir.go b/weed/server/filer_server_handlers_read_dir.go index 9ca0209f4..99345550c 100644 --- a/weed/server/filer_server_handlers_read_dir.go +++ b/weed/server/filer_server_handlers_read_dir.go @@ -2,6 +2,9 @@ package weed_server import ( "context" + "encoding/base64" + "fmt" + "github.com/skip2/go-qrcode" "net/http" "strconv" "strings" @@ -65,21 +68,30 @@ func (fs *FilerServer) listDirectoryHandler(w http.ResponseWriter, r *http.Reque lastFileName, shouldDisplayLoadMore, }) - } else { - ui.StatusTpl.Execute(w, struct { - Path string - Breadcrumbs []ui.Breadcrumb - Entries interface{} - Limit int - LastFileName string - ShouldDisplayLoadMore bool - }{ - path, - ui.ToBreadcrumb(path), - entries, - limit, - lastFileName, - shouldDisplayLoadMore, - }) + return + } + + var qrImageString string + img, err := qrcode.Encode(fmt.Sprintf("http://%s:%d%s", fs.option.Host, fs.option.Port, r.URL.Path), qrcode.Medium, 128) + if err == nil { + qrImageString = base64.StdEncoding.EncodeToString(img) } + + ui.StatusTpl.Execute(w, struct { + Path string + Breadcrumbs []ui.Breadcrumb + Entries interface{} + Limit int + LastFileName string + ShouldDisplayLoadMore bool + QrImage string + }{ + path, + ui.ToBreadcrumb(path), + entries, + limit, + lastFileName, + shouldDisplayLoadMore, + qrImageString, + }) } diff --git a/weed/server/filer_ui/templates.go b/weed/server/filer_ui/templates.go index 04a81433b..f86dde5b1 100644 --- a/weed/server/filer_ui/templates.go +++ b/weed/server/filer_ui/templates.go @@ -21,9 +21,11 @@ var funcMap = template.FuncMap{ var StatusTpl = template.Must(template.New("status").Funcs(funcMap).Parse(`<!DOCTYPE html> <html> <head> - <title>SeaweedFS Filer</title> - <link rel="stylesheet" href="/seaweedfsstatic/bootstrap/3.3.1/css/bootstrap.min.css"> + <title>SeaweedFS Filer</title> + <meta name="viewport" content="width=device-width, initial-scale=1"> + <link rel="stylesheet" href="/seaweedfsstatic/bootstrap/3.3.1/css/bootstrap.min.css"> <style> +body { padding-bottom: 70px; } #drop-area { border: 1px transparent; } @@ -46,6 +48,11 @@ var StatusTpl = template.Must(template.New("status").Funcs(funcMap).Parse(`<!DOC #fileElem { display: none; } +.qrImage { + display: block; + margin-left: auto; + margin-right: auto; +} </style> </head> <body> @@ -116,6 +123,14 @@ var StatusTpl = template.Must(template.New("status").Funcs(funcMap).Parse(`<!DOC </a> </div> {{end}} + + <br/> + <br/> + + <div class="navbar navbar-fixed-bottom"> + <img src="data:image/png;base64,{{.QrImage}}" class="qrImage" /> + </div> + </div> </body> <script type="text/javascript"> |
