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.

133 lines
2.7 KiB

  1. package weed_server
  2. import (
  3. "bufio"
  4. "fmt"
  5. "github.com/chrislusf/seaweedfs/weed/glog"
  6. "github.com/chrislusf/seaweedfs/weed/storage/needle"
  7. "github.com/chrislusf/seaweedfs/weed/util"
  8. "net"
  9. "strings"
  10. )
  11. func (vs *VolumeServer) HandleTcpConnection(c net.Conn) {
  12. defer c.Close()
  13. glog.V(0).Infof("Serving writes from %s", c.RemoteAddr().String())
  14. bufReader := bufio.NewReaderSize(c, 1024*1024)
  15. bufWriter := bufio.NewWriterSize(c, 1024*1024)
  16. for {
  17. cmd, err := bufReader.ReadString('\n')
  18. if err != nil {
  19. glog.Errorf("read command from %s: %v", c.RemoteAddr().String(), err)
  20. return
  21. }
  22. switch cmd[0] {
  23. case '+':
  24. fileId := cmd[1:]
  25. err = vs.handleTcpPut(fileId, bufReader)
  26. if err == nil {
  27. bufWriter.Write([]byte("+OK\n"))
  28. } else {
  29. bufWriter.Write([]byte("-ERR " + string(err.Error()) + "\n"))
  30. }
  31. case '-':
  32. fileId := cmd[1:]
  33. err = vs.handleTcpDelete(fileId)
  34. if err == nil {
  35. bufWriter.Write([]byte("+OK\n"))
  36. } else {
  37. bufWriter.Write([]byte("-ERR " + string(err.Error()) + "\n"))
  38. }
  39. case '?':
  40. fileId := cmd[1:]
  41. err = vs.handleTcpGet(fileId, bufWriter)
  42. case '!':
  43. bufWriter.Flush()
  44. }
  45. }
  46. }
  47. func (vs *VolumeServer) handleTcpGet(fileId string, writer *bufio.Writer) (err error) {
  48. volumeId, n, err2 := vs.parseFileId(fileId)
  49. if err2 != nil {
  50. return err2
  51. }
  52. volume := vs.store.GetVolume(volumeId)
  53. if volume == nil {
  54. return fmt.Errorf("volume %d not found", volumeId)
  55. }
  56. err = volume.StreamRead(n, writer)
  57. if err != nil {
  58. return err
  59. }
  60. return nil
  61. }
  62. func (vs *VolumeServer) handleTcpPut(fileId string, bufReader *bufio.Reader) (err error) {
  63. volumeId, n, err2 := vs.parseFileId(fileId)
  64. if err2 != nil {
  65. return err2
  66. }
  67. volume := vs.store.GetVolume(volumeId)
  68. if volume == nil {
  69. return fmt.Errorf("volume %d not found", volumeId)
  70. }
  71. sizeBuf := make([]byte, 4)
  72. if _, err = bufReader.Read(sizeBuf); err != nil {
  73. return err
  74. }
  75. dataSize := util.BytesToUint32(sizeBuf)
  76. err = volume.StreamWrite(n, bufReader, dataSize)
  77. if err != nil {
  78. return err
  79. }
  80. return nil
  81. }
  82. func (vs *VolumeServer) handleTcpDelete(fileId string) (err error) {
  83. volumeId, n, err2 := vs.parseFileId(fileId)
  84. if err2 != nil {
  85. return err2
  86. }
  87. _, err = vs.store.DeleteVolumeNeedle(volumeId, n)
  88. if err != nil {
  89. return err
  90. }
  91. return nil
  92. }
  93. func (vs *VolumeServer) parseFileId(fileId string) (needle.VolumeId, *needle.Needle, error) {
  94. commaIndex := strings.LastIndex(fileId, ",")
  95. if commaIndex <= 0 {
  96. return 0, nil, fmt.Errorf("unknown fileId %s", fileId)
  97. }
  98. vid, fid := fileId[0:commaIndex], fileId[commaIndex+1:]
  99. volumeId, ve := needle.NewVolumeId(vid)
  100. if ve != nil {
  101. return 0, nil, fmt.Errorf("unknown volume id in fileId %s", fileId)
  102. }
  103. n := new(needle.Needle)
  104. n.ParsePath(fid)
  105. return volumeId, n, nil
  106. }