|
|
@ -1,6 +1,7 @@
|
|
|
|
package master
|
|
|
|
package master
|
|
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
import (
|
|
|
|
|
|
|
|
"io"
|
|
|
|
"os"
|
|
|
|
"os"
|
|
|
|
"time"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
|
|
|
@ -17,7 +18,12 @@ type Addresser interface {
|
|
|
|
// Client is the client of the master server.
|
|
|
|
// Client is the client of the master server.
|
|
|
|
type Client struct {
|
|
|
|
type Client struct {
|
|
|
|
conn *connection.Conn
|
|
|
|
conn *connection.Conn
|
|
|
|
ch chan []byte
|
|
|
|
ch chan record
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
type record struct {
|
|
|
|
|
|
|
|
r []byte
|
|
|
|
|
|
|
|
err error
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// NewClient creates a new Client.
|
|
|
|
// NewClient creates a new Client.
|
|
|
@ -27,7 +33,7 @@ type Client struct {
|
|
|
|
func NewClient(addr Addresser, bufSize int) *Client {
|
|
|
|
func NewClient(addr Addresser, bufSize int) *Client {
|
|
|
|
c := &Client{}
|
|
|
|
c := &Client{}
|
|
|
|
c.conn = connection.New()
|
|
|
|
c.conn = connection.New()
|
|
|
|
c.ch = make(chan []byte, bufSize)
|
|
|
|
c.ch = make(chan record, bufSize)
|
|
|
|
go c.monitorMaster(addr)
|
|
|
|
go c.monitorMaster(addr)
|
|
|
|
go c.getRecords()
|
|
|
|
go c.getRecords()
|
|
|
|
return c
|
|
|
|
return c
|
|
|
@ -52,18 +58,20 @@ func (c *Client) getRecords() {
|
|
|
|
|
|
|
|
|
|
|
|
s := recordio.NewRangeScanner(f, &chunk.Index, -1, -1)
|
|
|
|
s := recordio.NewRangeScanner(f, &chunk.Index, -1, -1)
|
|
|
|
for s.Scan() {
|
|
|
|
for s.Scan() {
|
|
|
|
c.ch <- s.Record()
|
|
|
|
c.ch <- record{s.Record(), nil}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if s.Err() != nil {
|
|
|
|
if s.Err() != nil {
|
|
|
|
|
|
|
|
c.ch <- record{nil, s.Err()}
|
|
|
|
log.Errorln(err, chunk.Path)
|
|
|
|
log.Errorln(err, chunk.Path)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
err = f.Close()
|
|
|
|
err = f.Close()
|
|
|
|
c.ch <- nil
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
if err != nil {
|
|
|
|
log.Errorln(err)
|
|
|
|
log.Errorln(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
c.ch <- record{nil, io.EOF}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// We treat a task as finished whenever the last data
|
|
|
|
// We treat a task as finished whenever the last data
|
|
|
@ -133,6 +141,7 @@ func (c *Client) taskFinished(taskID int) error {
|
|
|
|
//
|
|
|
|
//
|
|
|
|
// NextRecord will block until the next record is available. It is
|
|
|
|
// NextRecord will block until the next record is available. It is
|
|
|
|
// thread-safe.
|
|
|
|
// thread-safe.
|
|
|
|
func (c *Client) NextRecord() []byte {
|
|
|
|
func (c *Client) NextRecord() ([]byte, error) {
|
|
|
|
return <-c.ch
|
|
|
|
r := <-c.ch
|
|
|
|
|
|
|
|
return r.r, r.err
|
|
|
|
}
|
|
|
|
}
|
|
|
|