<commit_before>// Package einhorn allows you to communicate with the einhorn master from a Go
// worker.
package einhorn

import (
	"bufio"
	"fmt"
	"net"
	"net/url"
	"path"

	"launchpad.net/goyaml"
)

var TmpDir = "/tmp"

type Client struct {
	socket net.Conn
	reader *bufio.Reader
	writer *bufio.Writer
}

type ClientRequest struct {
	RequestId int `yaml:"request_id,omitempty"`
	Command   string
	Args      []string `yaml:",omitempty"`
}

type ClientAckRequest struct {
	Command string
	Pid     int
}

type ClientResponse struct {
	RequestId int `yaml:"request_id"`
	Message   string
	Wait      bool
}

func NewClient(socket net.Conn) *Client {
	return &Client{
		socket: socket,
		reader: bufio.NewReader(socket),
		writer: bufio.NewWriter(socket),
	}
}

func NewClientForPath(path string) (*Client, error) {
	socket, err := net.Dial("unix", path)
	if err != nil {
		return nil, err
	}

	return NewClient(socket), nil
}

func NewClientForName(name string) (*Client, error) {
	return NewClientForPath(path.Join(TmpDir, fmt.Sprintf("einhorn-%s.sock", name)))
}

func (c *Client) SendRequest(req interface{}) error {
	line, err := goyaml.Marshal(req)
	if err != nil {
		return err
	}

	encoded := url.QueryEscape(string(line))

	if _, err := c.writer.WriteString(encoded); err != nil {<commit_msg>Fix encoding of command strings sent to the einhorn master<commit_after>// Package einhorn allows you to communicate with the einhorn master from a Go
// worker.
package einhorn

import (
	"bufio"
	"bytes"
	"fmt"
	"net"
	"net/url"
	"path"

	"launchpad.net/goyaml"
)

var TmpDir = "/tmp"

type Client struct {
	socket net.Conn
	reader *bufio.Reader
	writer *bufio.Writer
}

type ClientRequest struct {
	RequestId int `yaml:"request_id,omitempty"`
	Command   string
	Args      []string `yaml:",omitempty"`
}

type ClientAckRequest struct {
	Command string
	Pid     int
}

type ClientResponse struct {
	RequestId int `yaml:"request_id"`
	Message   string
	Wait      bool
}

func NewClient(socket net.Conn) *Client {
	return &Client{
		socket: socket,
		reader: bufio.NewReader(socket),
		writer: bufio.NewWriter(socket),
	}
}

func NewClientForPath(path string) (*Client, error) {
	socket, err := net.Dial("unix", path)
	if err != nil {
		return nil, err
	}

	return NewClient(socket), nil
}

func NewClientForName(name string) (*Client, error) {
	return NewClientForPath(path.Join(TmpDir, fmt.Sprintf("einhorn-%s.sock", name)))
}

func (c *Client) SendRequest(req interface{}) error {
	line, err := goyaml.Marshal(req)
	if err != nil {
		return err
	}

	encoded := bytes.Replace(
		bytes.Replace(line, []byte("%"), []byte("%25"), -1),
		[]byte("\n"),
		[]byte("%0A"),
		-1)

	if _, err := c.writer.Write(encoded); err != nil {
{'fraction_non_alphanumeric': 0.13634693127526645, 'fraction_numerical': 0.0018375597206909224, 'mean_word_length': 4.106941838649155, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2800705', 'n_tokens_mistral': 972, 'n_tokens_neox': 944, 'n_words': 265}