nuclei/pkg/core/workpool.go

92 lines
2.9 KiB
Go
Raw Normal View History

2021-10-27 16:50:36 +05:30
package core
import (
"context"
"github.com/projectdiscovery/gologger"
"github.com/projectdiscovery/nuclei/v3/pkg/templates/types"
2024-04-03 17:50:57 +02:00
syncutil "github.com/projectdiscovery/utils/sync"
)
// WorkPool implements an execution pool for executing different
// types of task with different concurrency requirements.
//
// It also allows Configuration of such requirements. This is used
// for per-module like separate headless concurrency etc.
type WorkPool struct {
2024-04-03 17:50:57 +02:00
Headless *syncutil.AdaptiveWaitGroup
Default *syncutil.AdaptiveWaitGroup
config WorkPoolConfig
}
// WorkPoolConfig is the configuration for work pool
type WorkPoolConfig struct {
// InputConcurrency is the concurrency for inputs values.
InputConcurrency int
// TypeConcurrency is the concurrency for the request type templates.
TypeConcurrency int
// HeadlessInputConcurrency is the concurrency for headless inputs values.
HeadlessInputConcurrency int
// TypeConcurrency is the concurrency for the headless request type templates.
HeadlessTypeConcurrency int
}
2021-10-27 16:50:36 +05:30
// NewWorkPool returns a new WorkPool instance
func NewWorkPool(config WorkPoolConfig) *WorkPool {
2024-04-03 17:50:57 +02:00
headlessWg, _ := syncutil.New(syncutil.WithSize(config.HeadlessTypeConcurrency))
defaultWg, _ := syncutil.New(syncutil.WithSize(config.TypeConcurrency))
return &WorkPool{
config: config,
2024-04-03 17:50:57 +02:00
Headless: headlessWg,
Default: defaultWg,
}
}
// Wait waits for all the work pool wait groups to finish
func (w *WorkPool) Wait() {
w.Default.Wait()
w.Headless.Wait()
}
// InputPool returns a work pool for an input type
2024-04-03 17:50:57 +02:00
func (w *WorkPool) InputPool(templateType types.ProtocolType) *syncutil.AdaptiveWaitGroup {
var count int
2021-11-03 18:58:00 +05:30
if templateType == types.HeadlessProtocol {
count = w.config.HeadlessInputConcurrency
} else {
count = w.config.InputConcurrency
}
2024-04-03 17:50:57 +02:00
swg, _ := syncutil.New(syncutil.WithSize(count))
return swg
}
2024-04-03 18:50:46 +02:00
func (w *WorkPool) RefreshWithConfig(config WorkPoolConfig) {
if w.config.TypeConcurrency != config.TypeConcurrency {
w.config.TypeConcurrency = config.TypeConcurrency
}
if w.config.HeadlessTypeConcurrency != config.HeadlessTypeConcurrency {
w.config.HeadlessTypeConcurrency = config.HeadlessTypeConcurrency
}
if w.config.InputConcurrency != config.InputConcurrency {
w.config.InputConcurrency = config.InputConcurrency
}
if w.config.HeadlessInputConcurrency != config.HeadlessInputConcurrency {
w.config.HeadlessInputConcurrency = config.HeadlessInputConcurrency
}
w.Refresh(context.Background())
2024-04-03 18:50:46 +02:00
}
func (w *WorkPool) Refresh(ctx context.Context) {
2024-04-03 18:50:46 +02:00
if w.Default.Size != w.config.TypeConcurrency {
if err := w.Default.Resize(ctx, w.config.TypeConcurrency); err != nil {
gologger.Warning().Msgf("Could not resize workpool: %s\n", err)
}
2024-04-03 18:50:46 +02:00
}
if w.Headless.Size != w.config.HeadlessTypeConcurrency {
if err := w.Headless.Resize(ctx, w.config.HeadlessTypeConcurrency); err != nil {
gologger.Warning().Msgf("Could not resize workpool: %s\n", err)
}
2024-04-03 18:50:46 +02:00
}
}