Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reverted the change related to dynamic setting of gunicorn worker count #375

Merged
merged 1 commit into from
Oct 3, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 27 additions & 39 deletions src/startupscriptgenerator/src/python/scriptgenerator.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,27 +11,24 @@ import (
"fmt"
"os"
"path/filepath"
"runtime"
"strconv"
"strings"
)


type PythonStartupScriptGenerator struct {
AppPath string
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All these whitespace changes were done by VS Code automatically

UserStartupCommand string
DefaultAppPath string
DefaultAppModule string
DefaultAppDebugModule string
DebugAdapter string // Remote debugger adapter to use. Currently, only `ptvsd` is supported.
DebugPort string
DebugWait bool // Whether debugger adapter should pause and wait for a client
// connection before running the app.
BindPort string
VirtualEnvName string
PackageDirectory string
SkipVirtualEnvExtraction bool
Manifest common.BuildManifest
AppPath string
UserStartupCommand string
DefaultAppPath string
DefaultAppModule string
DefaultAppDebugModule string
DebugAdapter string // Remote debugger adapter to use. Currently, only `ptvsd` is supported.
DebugPort string
DebugWait bool // Whether debugger adapter should pause and wait for a client
// connection before running the app.
BindPort string
VirtualEnvName string
PackageDirectory string
SkipVirtualEnvExtraction bool
Manifest common.BuildManifest
}

const SupportedDebugAdapter = "ptvsd" // Not using an array since there's only one at the moment
Expand All @@ -57,12 +54,12 @@ func (gen *PythonStartupScriptGenerator) GenerateEntrypointScript() string {
packageSetupBlock := gen.getPackageSetupCommand()
scriptBuilder.WriteString(packageSetupBlock)

appType := "" // "Django", "Flask", etc.
appType := "" // "Django", "Flask", etc.
appDebugAdapter := "" // Used debugger adapter
appDirectory := ""
appModule := "" // Suspected entry module in app
appModule := "" // Suspected entry module in app
appDebugModule := "" // Command to run under a debugger in case debugging mode was requested

command := gen.UserStartupCommand // A custom command takes precedence over any framework defaults
if command != "" {
isPermissionAdded := common.ParseCommandAndAddExecutionPermission(gen.UserStartupCommand, gen.AppPath)
Expand All @@ -73,16 +70,16 @@ func (gen *PythonStartupScriptGenerator) GenerateEntrypointScript() string {

if appFw != nil {
println("Detected an app based on " + appFw.Name())
appType = appFw.Name()
appDirectory = gen.AppPath
appModule = appFw.GetGunicornModuleArg()
appType = appFw.Name()
appDirectory = gen.AppPath
appModule = appFw.GetGunicornModuleArg()
appDebugModule = appFw.GetDebuggableModule()
} else {
println("No framework detected; using default app from " + gen.DefaultAppPath)
logger.LogInformation("Using default app '%s'", gen.DefaultAppPath)
appType = "Default"
appDirectory = gen.DefaultAppPath
appModule = gen.DefaultAppModule
appType = "Default"
appDirectory = gen.DefaultAppPath
appModule = gen.DefaultAppModule
appDebugModule = gen.DefaultAppDebugModule
}

Expand All @@ -104,8 +101,8 @@ func (gen *PythonStartupScriptGenerator) GenerateEntrypointScript() string {

logger.LogProperties(
"Finalizing script",
map[string]string { "appType": appType, "appDebugAdapter": appDebugAdapter,
"appModule": appModule, "venv": gen.Manifest.VirtualEnvName })
map[string]string{"appType": appType, "appDebugAdapter": appDebugAdapter,
"appModule": appModule, "venv": gen.Manifest.VirtualEnvName})

var runScript = scriptBuilder.String()
logger.LogInformation("Run script content:\n" + runScript)
Expand Down Expand Up @@ -216,10 +213,8 @@ func getVenvHandlingScript(virtualEnvName string, virtualEnvDir string) string {
// `module` is of the pattern "<dotted module path>:<variable name>".
// The variable name refers to a WSGI callable that should be found in the specified module.
func (gen *PythonStartupScriptGenerator) buildGunicornCommandForModule(module string, appDir string) string {
workerCount := getWorkerCount()

// Default to App Service's timeout value (in seconds)
args := "--timeout 600 --access-logfile '-' --error-logfile '-' --workers=" + workerCount
args := "--timeout 600 --access-logfile '-' --error-logfile '-'"

if gen.BindPort != "" {
args = appendArgs(args, "--bind="+DefaultHost+":"+gen.BindPort)
Expand Down Expand Up @@ -264,7 +259,7 @@ func (gen *PythonStartupScriptGenerator) buildPtvsdCommandForModule(moduleAndArg
}

pycmd := fmt.Sprintf("%spython -m ptvsd --host %s --port %s %s -m %s",
cdcmd, DefaultHost, gen.DebugPort, waitarg, moduleAndArgs)
cdcmd, DefaultHost, gen.DebugPort, waitarg, moduleAndArgs)

return cdcmd + pycmd
}
Expand All @@ -276,10 +271,3 @@ func appendArgs(currentArgs string, argToAppend string) string {
currentArgs += argToAppend
return currentArgs
}

func getWorkerCount() string {
// http://docs.gunicorn.org/en/stable/design.html#how-many-workers
cpuCount := runtime.NumCPU()
workerCount := (2 * cpuCount) + 1
return strconv.Itoa(workerCount)
}
29 changes: 6 additions & 23 deletions src/startupscriptgenerator/src/python/scriptgenerator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,15 @@
package main

import (
"runtime"
"strconv"
"testing"

"github.com/stretchr/testify/assert"
)

func Test_ExamplePythonStartupScriptGenerator_buildGunicornCommandForModule_onlyModule(t *testing.T) {
// Arrange
workerCount := getWorkerCount()
expected := "GUNICORN_CMD_ARGS=\"--timeout 600 --access-logfile '-' --error-logfile '-' --workers=" +
workerCount + "\" gunicorn module.py"
expected := "GUNICORN_CMD_ARGS=\"--timeout 600 --access-logfile '-' --error-logfile '-'" +
"\" gunicorn module.py"
gen := PythonStartupScriptGenerator{
BindPort: "",
}
Expand All @@ -31,9 +28,8 @@ func Test_ExamplePythonStartupScriptGenerator_buildGunicornCommandForModule_only

func ExamplePythonStartupScriptGenerator_buildGunicornCommandForModule_moduleAndPath(t *testing.T) {
// Arrange
workerCount := getWorkerCount()
expected := "GUNICORN_CMD_ARGS=\"--timeout 600 --access-logfile '-' --error-logfile '-' --workders=" +
workerCount + " --chdir=/a/b/c\" gunicorn module.py"
expected := "GUNICORN_CMD_ARGS=\"--timeout 600 --access-logfile '-' --error-logfile '-'" +
" --chdir=/a/b/c\" gunicorn module.py"
gen := PythonStartupScriptGenerator{
BindPort: "",
}
Expand All @@ -47,9 +43,8 @@ func ExamplePythonStartupScriptGenerator_buildGunicornCommandForModule_moduleAnd

func ExamplePythonStartupScriptGenerator_buildGunicornCommandForModule_moduleAndPathAndHost(t *testing.T) {
// Arrange
workerCount := getWorkerCount()
expected := "GUNICORN_CMD_ARGS=\"--timeout 600 --access-logfile '-' --error-logfile '-' --workers=" +
workerCount + "--bind=0.0.0.0:12345 --chdir=/a/b/c\" gunicorn module.py"
expected := "GUNICORN_CMD_ARGS=\"--timeout 600 --access-logfile '-' --error-logfile '-'" +
" --bind=0.0.0.0:12345 --chdir=/a/b/c\" gunicorn module.py"
gen := PythonStartupScriptGenerator{
BindPort: "12345",
}
Expand All @@ -60,15 +55,3 @@ func ExamplePythonStartupScriptGenerator_buildGunicornCommandForModule_moduleAnd
// Assert
assert.Equal(t, expected, actual)
}

func Test_GetsWorkerCountBasedOnNumberOfCores(t *testing.T) {
// Arrange
cpuCount := runtime.NumCPU()
expected := strconv.Itoa((2 * cpuCount) + 1)

// Act
actual := getWorkerCount()

// Assert
assert.Equal(t, expected, actual)
}