You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

53 lines
1.4 KiB

6 years ago
  1. package weed_server
  2. import (
  3. "fmt"
  4. "github.com/chrislusf/seaweedfs/weed/storage/types"
  5. "io"
  6. "os"
  7. "github.com/chrislusf/seaweedfs/weed/pb/volume_server_pb"
  8. "github.com/chrislusf/seaweedfs/weed/storage"
  9. )
  10. func (vs *VolumeServer) VolumeFollow(req *volume_server_pb.VolumeFollowRequest, stream volume_server_pb.VolumeServer_VolumeFollowServer) error {
  11. v := vs.store.GetVolume(storage.VolumeId(req.VolumeId))
  12. if v == nil {
  13. return fmt.Errorf("not found volume id %d", req.VolumeId)
  14. }
  15. stopOffset := v.Size()
  16. foundOffset, isLastOne, err := v.BinarySearchByAppendAtNs(req.Since)
  17. if err != nil {
  18. return fmt.Errorf("fail to locate by appendAtNs: %s", err)
  19. }
  20. if isLastOne {
  21. return nil
  22. }
  23. startOffset := int64(foundOffset) * int64(types.NeedleEntrySize)
  24. buf := make([]byte, 1024*1024*2)
  25. return sendFileContent(v.DataFile(), buf, startOffset, stopOffset, stream)
  26. }
  27. func sendFileContent(datFile *os.File, buf []byte, startOffset, stopOffset int64, stream volume_server_pb.VolumeServer_VolumeFollowServer) error {
  28. var blockSizeLimit = int64(len(buf))
  29. for i := int64(0); i < stopOffset-startOffset; i += blockSizeLimit {
  30. n, readErr := datFile.ReadAt(buf, startOffset+i)
  31. if readErr == nil || readErr == io.EOF {
  32. resp := &volume_server_pb.VolumeFollowResponse{}
  33. resp.FileContent = buf[i : i+int64(n)]
  34. sendErr := stream.Send(resp)
  35. if sendErr != nil {
  36. return sendErr
  37. }
  38. } else {
  39. return readErr
  40. }
  41. }
  42. return nil
  43. }