<commit_before>package gordon

import (
	"time"

	"github.com/vito/gordon/connection"
	"github.com/vito/gordon/warden"
)

type Client interface {
	Connect() error

	Create() (*warden.CreateResponse, error)
	Stop(handle string, background, kill bool) (*warden.StopResponse, error)
	Destroy(handle string) (*warden.DestroyResponse, error)
	Run(handle, script string) (uint32, <-chan *warden.ProcessPayload, error)
	Attach(handle string, processID uint32) (<-chan *warden.ProcessPayload, error)
	NetIn(handle string) (*warden.NetInResponse, error)
	LimitMemory(handle string, limit uint64) (*warden.LimitMemoryResponse, error)
	GetMemoryLimit(handle string) (uint64, error)
	LimitDisk(handle string, limit uint64) (*warden.LimitDiskResponse, error)
	GetDiskLimit(handle string) (uint64, error)
	List() (*warden.ListResponse, error)
	Info(handle string) (*warden.InfoResponse, error)
	CopyIn(handle, src, dst string) (*warden.CopyInResponse, error)
}

type client struct {
	connectionProvider ConnectionProvider
	connection         chan *connection.Connection
}

func NewClient(cp ConnectionProvider) Client {
	return &client{
		connectionProvider: cp,
		connection:         make(chan *connection.Connection),
	}
}

func (c *client) Connect() error {
	conn, err := c.connectionProvider.ProvideConnection()
	if err != nil {
		return err
	}

	go c.serveConnection(conn)

	return nil
}

func (c *client) Create() (*warden.CreateResponse, error) {
	conn := c.acquireConnection()
	defer c.release(conn)

	return conn.Create()
}

func (c *client) Stop(handle string, background, kill bool) (*warden.StopResponse, error) {
	conn := c.acquireConnection()
	defer c.release(conn)

	return conn.Stop(handle, background, kill)
}

func (c *client) Destroy(handle string) (*warden.DestroyResponse, error) {
	conn := c.acquireConnection()
	defer c.release(conn)

	return conn.Destroy(handle)
}

func (c *client) Run(handle, script string) (uint32, <-chan *warden.ProcessPayload, error) {
	conn := c.acquireConnection()
	defer c.release(conn)

	processID, stream, err := conn.Run(handle, script)<commit_msg>fix early connection release in Run<commit_after>package gordon

import (
	"time"

	"github.com/vito/gordon/connection"
	"github.com/vito/gordon/warden"
)

type Client interface {
	Connect() error

	Create() (*warden.CreateResponse, error)
	Stop(handle string, background, kill bool) (*warden.StopResponse, error)
	Destroy(handle string) (*warden.DestroyResponse, error)
	Run(handle, script string) (uint32, <-chan *warden.ProcessPayload, error)
	Attach(handle string, processID uint32) (<-chan *warden.ProcessPayload, error)
	NetIn(handle string) (*warden.NetInResponse, error)
	LimitMemory(handle string, limit uint64) (*warden.LimitMemoryResponse, error)
	GetMemoryLimit(handle string) (uint64, error)
	LimitDisk(handle string, limit uint64) (*warden.LimitDiskResponse, error)
	GetDiskLimit(handle string) (uint64, error)
	List() (*warden.ListResponse, error)
	Info(handle string) (*warden.InfoResponse, error)
	CopyIn(handle, src, dst string) (*warden.CopyInResponse, error)
}

type client struct {
	connectionProvider ConnectionProvider
	connection         chan *connection.Connection
}

func NewClient(cp ConnectionProvider) Client {
	return &client{
		connectionProvider: cp,
		connection:         make(chan *connection.Connection),
	}
}

func (c *client) Connect() error {
	conn, err := c.connectionProvider.ProvideConnection()
	if err != nil {
		return err
	}

	go c.serveConnection(conn)

	return nil
}

func (c *client) Create() (*warden.CreateResponse, error) {
	conn := c.acquireConnection()
	defer c.release(conn)

	return conn.Create()
}

func (c *client) Stop(handle string, background, kill bool) (*warden.StopResponse, error) {
	conn := c.acquireConnection()
	defer c.release(conn)

	return conn.Stop(handle, background, kill)
}

func (c *client) Destroy(handle string) (*warden.DestroyResponse, error) {
	conn := c.acquireConnection()
	defer c.release(conn)

	return conn.Destroy(handle)
}

func (c *client) Run(handle, script string) (uint32, <-chan *warden.ProcessPayload, error) {
	conn := c.acquireConnection()

	processID, stream, err := conn.Run(handle, script)
{'fraction_non_alphanumeric': 0.12724658519051044, 'fraction_numerical': 0.006709801102324467, 'mean_word_length': 5.501557632398754, 'pattern_counts': {'":': 0, '<': 9, '<?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': '1288252', 'n_tokens_mistral': 1365, 'n_tokens_neox': 1319, 'n_words': 350}