Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
projectdiscovery
GitHub Repository: projectdiscovery/nuclei
Path: blob/dev/pkg/core/workpool.go
2070 views
1
package core
2
3
import (
4
"context"
5
6
"github.com/projectdiscovery/gologger"
7
"github.com/projectdiscovery/nuclei/v3/pkg/templates/types"
8
syncutil "github.com/projectdiscovery/utils/sync"
9
)
10
11
// WorkPool implements an execution pool for executing different
12
// types of task with different concurrency requirements.
13
//
14
// It also allows Configuration of such requirements. This is used
15
// for per-module like separate headless concurrency etc.
16
type WorkPool struct {
17
Headless *syncutil.AdaptiveWaitGroup
18
Default *syncutil.AdaptiveWaitGroup
19
config WorkPoolConfig
20
}
21
22
// WorkPoolConfig is the configuration for work pool
23
type WorkPoolConfig struct {
24
// InputConcurrency is the concurrency for inputs values.
25
InputConcurrency int
26
// TypeConcurrency is the concurrency for the request type templates.
27
TypeConcurrency int
28
// HeadlessInputConcurrency is the concurrency for headless inputs values.
29
HeadlessInputConcurrency int
30
// TypeConcurrency is the concurrency for the headless request type templates.
31
HeadlessTypeConcurrency int
32
}
33
34
// NewWorkPool returns a new WorkPool instance
35
func NewWorkPool(config WorkPoolConfig) *WorkPool {
36
headlessWg, _ := syncutil.New(syncutil.WithSize(config.HeadlessTypeConcurrency))
37
defaultWg, _ := syncutil.New(syncutil.WithSize(config.TypeConcurrency))
38
39
return &WorkPool{
40
config: config,
41
Headless: headlessWg,
42
Default: defaultWg,
43
}
44
}
45
46
// Wait waits for all the work pool wait groups to finish
47
func (w *WorkPool) Wait() {
48
w.Default.Wait()
49
w.Headless.Wait()
50
}
51
52
// InputPool returns a work pool for an input type
53
func (w *WorkPool) InputPool(templateType types.ProtocolType) *syncutil.AdaptiveWaitGroup {
54
var count int
55
if templateType == types.HeadlessProtocol {
56
count = w.config.HeadlessInputConcurrency
57
} else {
58
count = w.config.InputConcurrency
59
}
60
swg, _ := syncutil.New(syncutil.WithSize(count))
61
return swg
62
}
63
64
func (w *WorkPool) RefreshWithConfig(config WorkPoolConfig) {
65
if w.config.TypeConcurrency != config.TypeConcurrency {
66
w.config.TypeConcurrency = config.TypeConcurrency
67
}
68
if w.config.HeadlessTypeConcurrency != config.HeadlessTypeConcurrency {
69
w.config.HeadlessTypeConcurrency = config.HeadlessTypeConcurrency
70
}
71
if w.config.InputConcurrency != config.InputConcurrency {
72
w.config.InputConcurrency = config.InputConcurrency
73
}
74
if w.config.HeadlessInputConcurrency != config.HeadlessInputConcurrency {
75
w.config.HeadlessInputConcurrency = config.HeadlessInputConcurrency
76
}
77
w.Refresh(context.Background())
78
}
79
80
func (w *WorkPool) Refresh(ctx context.Context) {
81
if w.Default.Size != w.config.TypeConcurrency {
82
if err := w.Default.Resize(ctx, w.config.TypeConcurrency); err != nil {
83
gologger.Warning().Msgf("Could not resize workpool: %s\n", err)
84
}
85
}
86
if w.Headless.Size != w.config.HeadlessTypeConcurrency {
87
if err := w.Headless.Resize(ctx, w.config.HeadlessTypeConcurrency); err != nil {
88
gologger.Warning().Msgf("Could not resize workpool: %s\n", err)
89
}
90
}
91
}
92
93