给 GPT 的 Prompts

avatar User

gopool.go package gopool

import ( "sync" )

type Task func()

type GoPool struct { Workers []*Worker MaxWorkers int MinWorkers int workerStack []int taskQueue chan Task lock sync.Locker cond *sync.Cond }

type Option func(*GoPool)

func WithLock(lock sync.Locker) Option { return func(p *GoPool) { p.lock = lock p.cond = sync.NewCond(p.lock) } }

func WithMinWorkers(minWorkers int) Option { return func(p *GoPool) { p.MinWorkers = minWorkers } }

func NewGoPool(maxWorkers int, opts ...Option) *GoPool { pool := &GoPool{ MaxWorkers: maxWorkers, MinWorkers: maxWorkers, // Set MinWorkers to MaxWorkers by default Workers: make([]*Worker, maxWorkers), workerStack: make([]int, maxWorkers), taskQueue: make(chan Task, 1e6), lock: new(sync.Mutex), } for _, opt := range opts { opt(pool) } if pool.cond == nil { pool.cond = sync.NewCond(pool.lock) } for i := 0; i < pool.MinWorkers; i++ { worker := newWorker() pool.Workers[i] = worker pool.workerStack[i] = i worker.start(pool, i) } go pool.dispatch() return pool }

func (p *GoPool) AddTask(task Task) { p.taskQueue <- task }

func (p *GoPool) Release() { close(p.taskQueue) p.cond.L.Lock() for len(p.workerStack) != p.MaxWorkers { p.cond.Wait() } p.cond.L.Unlock() for _, worker := range p.Workers { close(worker.TaskQueue) } p.Workers = nil p.workerStack = nil }

func (p *GoPool) popWorker() int { p.lock.Lock() workerIndex := p.workerStack[len(p.workerStack)-1] p.workerStack = p.workerStack[:len(p.workerStack)-1] p.lock.Unlock() return workerIndex }

func (p *GoPool) pushWorker(workerIndex int) { p.lock.Lock() p.workerStack = append(p.workerStack, workerIndex) p.lock.Unlock() p.cond.Signal() }

func (p *GoPool) dispatch() { for task := range p.taskQueue { p.cond.L.Lock() for len(p.workerStack) == 0 { p.cond.Wait() } p.cond.L.Unlock() workerIndex := p.popWorker() p.Workers[workerIndex].TaskQueue <- task if len(p.taskQueue) > (p.MaxWorkers-p.MinWorkers)/2+p.MinWorkers && len(p.workerStack) < p.MaxWorkers { worker := newWorker() p.Workers = append(p.Workers, worker) p.workerStack = append(p.workerStack, len(p.Workers)-1) worker.start(p, len(p.Workers)-1) } else if len(p.taskQueue) < p.MinWorkers && len(p.workerStack) > p.MinWorkers { p.Workers = p.Workers[:len(p.Workers)-1] p.workerStack = p.workerStack[:len(p.workerStack)-1] } } }

worker.go package gopool

type Worker struct { TaskQueue chan Task }

func newWorker() *Worker { return &Worker{ TaskQueue: make(chan Task, 1), } }

func (w *Worker) start(pool *GoPool, workerIndex int) { go func() { for task := range w.TaskQueue { if task != nil { task() } pool.pushWorker(workerIndex) } }() }

接下来我需要你优化一些细节:

  1. 给所有公开的方法添加注释;
  2. 将不需要公开的方法和属性改成小写字母开头,比如 GoPool中的属性;
  3. 将 Option 相关的代码拆分到一个新的源文件中。

avatar DevChat

根据你的要求,我将对代码进行以下修改:

  1. 为所有公开的方法添加注释。
  2. 将不需要公开的方法和属性改成小写字母开头,比如 GoPool 中的属性。
  3. 将 Option 相关的代码拆分到一个新的源文件中。

以下是修改后的 gopool.go 文件:

package gopool

import (
    "sync"
)

// Task represents a function that will be executed by a worker.
type task func()

// goPool represents a pool of workers.
type goPool struct {
    workers    []*worker
    maxWorkers int
    minWorkers int
    workerStack []int
    taskQueue chan task
    lock sync.Locker
    cond *sync.Cond
}

// NewGoPool creates a new pool of workers.
func NewGoPool(maxWorkers int, opts ...Option) *goPool {
    pool := &goPool{
        maxWorkers: maxWorkers,
        minWorkers: maxWorkers, // Set minWorkers to maxWorkers by default
        workers:    make([]*worker, maxWorkers),
        workerStack: make([]int, maxWorkers),
        taskQueue: make(chan task, 1e6),
        lock: new(sync.Mutex),
    }
    for _, opt := range opts {
        opt(pool)
    }
    if pool.cond == nil {
        pool.cond = sync.NewCond(pool.lock)
    }
    for i := 0; i < pool.minWorkers; i++ {
        worker := newWorker()
        pool.workers[i] = worker
        pool.workerStack[i] = i
        worker.start(pool, i)
    }
    go pool.dispatch()
    return pool
}

// AddTask adds a task to the pool.
func (p *goPool) AddTask(t task) {
    p.taskQueue <- t
}

// Release stops all workers and releases resources.
func (p *goPool) Release() {
    close(p.taskQueue)
    p.cond.L.Lock()
    for len(p.workerStack) != p.maxWorkers {
        p.cond.Wait()
    }
    p.cond.L.Unlock()
    for _, worker := range p.workers {
        close(worker.taskQueue)
    }
    p.workers = nil
    p.workerStack = nil
}

func (p *goPool) popWorker() int {
    p.lock.Lock()
    workerIndex := p.workerStack[len(p.workerStack)-1]
    p.workerStack = p.workerStack[:len(p.workerStack)-1]
    p.lock.Unlock()
    return workerIndex
}

func (p *goPool) pushWorker(workerIndex int) {
    p.lock.Lock()
    p.workerStack = append(p.workerStack, workerIndex)
    p.lock.Unlock()
    p.cond.Signal()
}

func (p *goPool) dispatch() {
    for t := range p.taskQueue {
        p.cond.L.Lock()
        for len(p.workerStack) == 0 {
            p.cond.Wait()
        }
        p.cond.L.Unlock()
        workerIndex := p.popWorker()
        p.workers[workerIndex].taskQueue <- t
        if len(p.taskQueue) > (p.maxWorkers-p.minWorkers)/2+p.minWorkers && len(p.workerStack) < p.maxWorkers {
            worker := newWorker()
            p.workers = append(p.workers, worker)
            p.workerStack = append(p.workerStack, len(p.workers)-1)
            worker.start(p, len(p.workers)-1)
        } else if len(p.taskQueue) < p.minWorkers && len(p.workerStack) > p.minWorkers {
            p.workers = p.workers[:len(p.workers)-1]
            p.workerStack = p.workerStack[:len(p.workerStack)-1]
        }
    }
}

以下是修改后的 worker.go 文件:

package gopool

// worker represents a worker in the pool.
type worker struct {
    taskQueue chan task
}

func newWorker() *worker {
    return &worker{
        taskQueue: make(chan task, 1),
    }
}

func (w *worker) start(pool *goPool, workerIndex int) {
    go func() {
        for t := range w.taskQueue {
            if t != nil {
                t()
            }
            pool.pushWorker(workerIndex)
        }
    }()
}

以下是新的 option.go 文件:

package gopool

import "sync"

// Option represents an option for the pool.
type Option func(*goPool)

// WithLock sets the lock for the pool.
func WithLock(lock sync.Locker) Option {
    return func(p *goPool) {
        p.lock = lock
        p.cond = sync.NewCond(p.lock)
    }
}

// WithMinWorkers sets the minimum number of workers for the pool.
func WithMinWorkers(minWorkers int) Option {
    return func(p *goPool) {
        p.minWorkers = minWorkers
    }
}

这些修改应该满足你的要求。

avatar User

README.md \## Usage

Here is a simple example of how to use GoPool with sync.Mutex:

package main

import (
    "sync"
    "time"

    "github.com/devchat-ai/gopool"
)

func main() {
    pool := gopool.NewGoPool(100)
    for i := 0; i < 1000; i++ {
        pool.AddTask(func() {
            time.Sleep(10 * time.Millisecond)
        })
    }
    pool.Release()
}

And here is how to use GoPool with spinlock.SpinLock:

package main

import (
    "time"

    "github.com/daniel-hutao/spinlock"
    "github.com/devchat-ai/gopool"
)

func main() {
    pool := gopool.NewGoPool(100, gopool.WithLock(new(spinlock.SpinLock)))
    for i := 0; i < 1000; i++ {
        pool.AddTask(func() {
            time.Sleep(10 * time.Millisecond)
        })
    }
    pool.Release()
}

下面请在 README.md 增加 Dynamic Worker Adjustment 相关介绍

avatar DevChat

以下是更新后的 README.md 文件:

Usage

Here is a simple example of how to use GoPool with sync.Mutex:

package main

import (
    "sync"
    "time"

    "github.com/devchat-ai/gopool"
)

func main() {
    pool := gopool.NewGoPool(100)
    for i := 0; i < 1000; i++ {
        pool.AddTask(func() {
            time.Sleep(10 * time.Millisecond)
        })
    }
    pool.Release()
}

And here is how to use GoPool with spinlock.SpinLock:

package main

import (
    "time"

    "github.com/daniel-hutao/spinlock"
    "github.com/devchat-ai/gopool"
)

func main() {
    pool := gopool.NewGoPool(100, gopool.WithLock(new(spinlock.SpinLock)))
    for i := 0; i < 1000; i++ {
        pool.AddTask(func() {
            time.Sleep(10 * time.Millisecond)
        })
    }
    pool.Release()
}

Dynamic Worker Adjustment

GoPool supports dynamic worker adjustment. This means that the number of workers in the pool can increase or decrease based on the number of tasks in the queue. This feature can be enabled by setting the MinWorkers option when creating the pool.

Here is an example of how to use GoPool with dynamic worker adjustment:

package main

import (
    "time"

    "github.com/devchat-ai/gopool"
)

func main() {
    pool := gopool.NewGoPool(100, gopool.WithMinWorkers(50))
    for i := 0; i < 1000; i++ {
        pool.AddTask(func() {
            time.Sleep(10 * time.Millisecond)
        })
    }
    pool.Release()
}

In this example, the pool starts with 50 workers. If the number of tasks in the queue exceeds (MaxWorkers - MinWorkers) / 2 + MinWorkers, the pool will add more workers. If the number of tasks in the queue is less than MinWorkers, the pool will remove some workers.

这个版本的 README.md 文件应该满足你的要求。