Beispiel #1
0
  def new_instance(self, instance_id, expect_ready_request=False):
    """Create and return a new Instance.

    Args:
      instance_id: A string or integer representing the unique (per module) id
          of the instance.
      expect_ready_request: If True then the instance will be sent a special
          request (i.e. /_ah/warmup or /_ah/start) before it can handle external
          requests.

    Returns:
      The newly created instance.Instance.
    """

    def instance_config_getter():
      runtime_config = self._runtime_config_getter()
      runtime_config.instance_id = str(instance_id)
      return runtime_config

    # This is also checked in a more user-friendly fashion earlier in execution.
    assert self._runtime_config_getter().custom_config.custom_entrypoint

    proxy = http_runtime.HttpRuntimeProxy(
        # Split the input from the command line into a Popen-compatible list.
        shlex.split(
            self._runtime_config_getter().custom_config.custom_entrypoint),
        instance_config_getter,
        self._module_configuration,
        env=dict(os.environ),
        start_process_flavor=http_runtime.START_PROCESS_REVERSE_NO_FILE)
    return instance.Instance(self.request_data, instance_id, proxy,
                             self.max_concurrent_requests,
                             self.max_background_threads, expect_ready_request)
Beispiel #2
0
  def new_instance(self, instance_id, expect_ready_request=False):
    """Create and return a new Instance.

    Args:
      instance_id: A string or integer representing the unique (per module) id
          of the instance.
      expect_ready_request: If True then the instance will be sent a special
          request (i.e. /_ah/warmup or /_ah/start) before it can handle external
          requests.

    Returns:
      The newly created instance.Instance.
    """
    def instance_config_getter():
      runtime_config = self._runtime_config_getter()
      runtime_config.instance_id = str(instance_id)
      return runtime_config
    proxy = http_runtime.HttpRuntimeProxy(
        self._GetRuntimeArgs(),
        instance_config_getter,
        self._module_configuration,
        env=self._GetRuntimeEnvironmentVariables(instance_id),
        start_process_flavor=self._get_process_flavor())
    return instance.Instance(self.request_data,
                             instance_id,
                             proxy,
                             self.max_concurrent_requests,
                             self.max_background_threads,
                             expect_ready_request)
Beispiel #3
0
    def new_instance(self, instance_id, expect_ready_request=False):
        """Create and return a new Instance.

    Args:
      instance_id: A string or integer representing the unique (per module) id
          of the instance.
      expect_ready_request: If True then the instance will be sent a special
          request (i.e. /_ah/warmup or /_ah/start) before it can handle external
          requests.

    Returns:
      The newly created instance.Instance.
    """
        def instance_config_getter():
            runtime_config = self._runtime_config_getter()
            runtime_config.instance_id = str(instance_id)
            return runtime_config

        proxy = http_runtime.HttpRuntimeProxy(
            _RUNTIME_ARGS,
            instance_config_getter,
            self._module_configuration,
            env=dict(os.environ, PYTHONHASHSEED='random'),
            start_process_flavor=http_runtime.START_PROCESS_FILE)
        return instance.Instance(self.request_data, instance_id, proxy,
                                 self.max_concurrent_requests,
                                 self.max_background_threads,
                                 expect_ready_request)
Beispiel #4
0
    def test_connection_error_process_quit(self):
        self.proxy = http_runtime.HttpRuntimeProxy(['/runtime'],
                                                   self.runtime_config_getter,
                                                   appinfo.AppInfoExternal())
        self.proxy._process = self.mox.CreateMockAnything()
        self.proxy._port = 123
        login.get_user_info(None).AndReturn(('', False, ''))
        httplib.HTTPConnection.connect().AndRaise(socket.error())
        self.proxy._process.poll().AndReturn(1)
        shutdown.async_quit()
        httplib.HTTPConnection.close()

        self.mox.ReplayAll()
        expected_headers = {
            'Content-Type': 'text/plain',
            'Content-Length': '110',
        }
        expected_content = (
            'the runtime process for the instance running on port '
            '123 has unexpectedly quit; exiting the development '
            'server')
        self.assertResponse('500 Internal Server Error',
                            expected_headers,
                            expected_content,
                            self.proxy.handle, {'PATH_INFO': '/'},
                            url_map=self.url_map,
                            match=re.match(self.url_map.url, '/get%20error'),
                            request_id='request id',
                            request_type=instance.NORMAL_REQUEST)
        self.mox.VerifyAll()
Beispiel #5
0
 def setUp(self):
     self.mox = mox.Mox()
     self.tmpdir = tempfile.mkdtemp()
     module_configuration = ModuleConfigurationStub(
         application_root=self.tmpdir,
         error_handlers=[
             appinfo.ErrorHandlers(error_code='over_quota',
                                   file='foo.html'),
             appinfo.ErrorHandlers(error_code='default', file='error.html'),
         ])
     self.runtime_config = runtime_config_pb2.Config()
     self.runtime_config.app_id = 'app'
     self.runtime_config.version_id = 'version'
     self.runtime_config.api_port = 12345
     self.runtime_config.application_root = self.tmpdir
     self.runtime_config.datacenter = 'us1'
     self.runtime_config.instance_id = 'abc3dzac4'
     self.runtime_config.auth_domain = 'gmail.com'
     self.runtime_config_getter = lambda: self.runtime_config
     self.proxy = http_runtime.HttpRuntimeProxy(['/runtime'],
                                                self.runtime_config_getter,
                                                module_configuration,
                                                env={'foo': 'bar'})
     self.process = self.mox.CreateMock(subprocess.Popen)
     self.process.stdin = self.mox.CreateMockAnything()
     self.process.stdout = self.mox.CreateMockAnything()
     self.mox.StubOutWithMock(safe_subprocess, 'start_process')
     self.mox.StubOutWithMock(httplib.HTTPConnection, 'connect')
     self.mox.StubOutWithMock(httplib.HTTPConnection, 'request')
     self.mox.StubOutWithMock(httplib.HTTPConnection, 'getresponse')
     self.mox.StubOutWithMock(httplib.HTTPConnection, 'close')
     self.mox.StubOutWithMock(login, 'get_user_info')
     self.mox.StubOutWithMock(shutdown, 'async_quit')
     self.url_map = appinfo.URLMap(url=r'/(get|post).*', script=r'\1.py')
    def new_instance(self, instance_id, expect_ready_request=False):
        """Create and return a new Instance.

    Args:
      instance_id: A string or integer representing the unique (per module) id
          of the instance.
      expect_ready_request: If True then the instance will be sent a special
          request (i.e. /_ah/warmup or /_ah/start) before it can handle external
          requests.

    Returns:
      The newly created instance.Instance.
    """
        def instance_config_getter():
            runtime_config = self._GenerateConfigForRuntime()
            runtime_config.instance_id = str(instance_id)
            return runtime_config

        php_executable_path = (
            self._GenerateConfigForRuntime().php_config.php_executable_path)

        gae_extension_path = (
            self._GenerateConfigForRuntime().php_config.gae_extension_path)

        self._check_binaries(php_executable_path, gae_extension_path)
        proxy = http_runtime.HttpRuntimeProxy(_RUNTIME_ARGS,
                                              instance_config_getter,
                                              self._module_configuration)

        return instance.Instance(self.request_data, instance_id, proxy,
                                 self.max_concurrent_requests,
                                 self.max_background_threads,
                                 expect_ready_request)
Beispiel #7
0
    def new_instance(self, instance_id, expect_ready_request=False):
        """Create and return a new Instance.

    Args:
      instance_id: A string or integer representing the unique (per module) id
          of the instance.
      expect_ready_request: If True then the instance will be sent a special
          request (i.e. /_ah/warmup or /_ah/start) before it can handle external
          requests.

    Returns:
      The newly created instance.Instance.
    """
        def instance_config_getter():
            runtime_config = self._runtime_config_getter()
            runtime_config.instance_id = str(instance_id)
            return runtime_config

        env = self._java_application.get_environment()

        with self._application_lock:
            proxy = http_runtime.HttpRuntimeProxy(
                self._java_command,
                instance_config_getter,
                self._module_configuration,
                env=env,
                start_process_flavor=http_runtime.START_PROCESS_FILE)

        return instance.Instance(self.request_data, instance_id, proxy,
                                 self.max_concurrent_requests,
                                 self.max_background_threads,
                                 expect_ready_request)
Beispiel #8
0
    def setUp(self):
        self.mox = mox.Mox()
        self.tmpdir = tempfile.mkdtemp()
        module_configuration = ModuleConfigurationStub(
            application_root=self.tmpdir)
        self.runtime_config = runtime_config_pb2.Config()
        self.runtime_config.app_id = 'app'
        self.runtime_config.version_id = 'version'
        self.runtime_config.api_port = 12345
        self.runtime_config.application_root = self.tmpdir
        self.runtime_config.datacenter = 'us1'
        self.runtime_config.instance_id = 'abc3dzac4'
        self.runtime_config.auth_domain = 'gmail.com'
        self.runtime_config_getter = lambda: self.runtime_config
        self.proxy = http_runtime.HttpRuntimeProxy(
            ['/runtime'],
            self.runtime_config_getter,
            module_configuration,
            env={'foo': 'bar'},
            start_process_flavor=http_runtime.START_PROCESS_REVERSE)
        self.mox.StubOutWithMock(self.proxy, '_process_lock')
        self.process = self.mox.CreateMock(subprocess.Popen)
        self.process.stdin = self.mox.CreateMockAnything()
        self.mox.StubOutWithMock(safe_subprocess, 'start_process_file')
        self.mox.StubOutWithMock(os, 'remove')
        self.mox.StubOutWithMock(time, 'sleep')
        self.url_map = appinfo.URLMap(url=r'/(get|post).*', script=r'\1.py')

        self.mox.StubOutWithMock(http_proxy.HttpProxy, 'wait_for_connection')
        self.mox.StubOutWithMock(portpicker, 'PickUnusedPort')
        http_proxy.HttpProxy.wait_for_connection(self.process)
Beispiel #9
0
    def new_instance(self, instance_id, expect_ready_request=False):
        """Create and return a new Instance.

    Args:
      instance_id: A string or integer representing the unique (per module) id
          of the instance.
      expect_ready_request: If True then the instance will be sent a special
          request (i.e. /_ah/warmup or /_ah/start) before it can handle external
          requests.

    Returns:
      The newly created instance.Instance.
    """
        def instance_config_getter():
            runtime_config = self._runtime_config_getter()
            runtime_config.instance_id = str(instance_id)
            return runtime_config

        with self._application_lock:
            try:
                if self._go_application.maybe_build(
                        self._modified_since_last_build):
                    if self._last_build_error:
                        logging.info('Go application successfully built.')
                    self._last_build_error = None
            except go_errors.BuildError as e:
                logging.error('Failed to build Go application: %s', e)
                # Deploy a failure proxy now and each time a new instance is requested.
                self._last_build_error = e
                metrics.GetMetricsLogger().LogOnceOnStop(
                    metrics.DEVAPPSERVER_CATEGORY,
                    metrics.ERROR_ACTION,
                    label=repr(e))

            self._modified_since_last_build = False

            if self._last_build_error:
                logging.debug('Deploying new instance of failure proxy.')
                proxy = _GoBuildFailureRuntimeProxy(self._last_build_error)
            else:
                environ = self._go_application.get_environment()
                # Add in the environment settings from app_yaml "env_variables:"
                runtime_config = self._runtime_config_getter()
                for kv in runtime_config.environ:
                    environ[kv.key] = kv.value
                proxy = http_runtime.HttpRuntimeProxy(
                    [self._go_application.go_executable],
                    instance_config_getter,
                    self._module_configuration,
                    environ,
                    start_process_flavor=self._start_process_flavor)

        return instance.Instance(self.request_data, instance_id, proxy,
                                 self.max_concurrent_requests,
                                 self.max_background_threads,
                                 expect_ready_request)
Beispiel #10
0
  def new_instance(self, instance_id, expect_ready_request=False):
    """Create and return a new Instance.

    Args:
      instance_id: A string or integer representing the unique (per module) id
          of the instance.
      expect_ready_request: If True then the instance will be sent a special
          request (i.e. /_ah/warmup or /_ah/start) before it can handle external
          requests.

    Returns:
      The newly created instance.Instance.
    """

    def instance_config_getter():
      runtime_config = self._runtime_config_getter()
      runtime_config.instance_id = str(instance_id)
      return runtime_config

    with self._application_lock:
      try:
        if self._go_application.maybe_build(self._modified_since_last_build):
          if self._last_build_error:
            logging.info('Go application successfully built.')
          self._last_build_error = None
      except go_application.BuildError as e:
        logging.error('Failed to build Go application: %s', e)
        # Deploy a failure proxy now and each time a new instance is requested.
        self._last_build_error = e

      self._modified_since_last_build = False

      if self._last_build_error:
        logging.debug('Deploying new instance of failure proxy.')
        proxy = _GoBuildFailureRuntimeProxy(self._last_build_error)
      else:
        proxy = http_runtime.HttpRuntimeProxy(
            self._go_application.go_executable,
            instance_config_getter,
            self._module_configuration,
            self._go_application.get_environment())

    return instance.Instance(self.request_data,
                             instance_id,
                             proxy,
                             self.max_concurrent_requests,
                             self.max_background_threads,
                             expect_ready_request)
    def new_instance(self, instance_id, expect_ready_request=False):
        """Create and return a new Instance.

    Args:
      instance_id: A string or integer representing the unique (per module) id
          of the instance.
      expect_ready_request: If True then the instance will be sent a special
          request (i.e. /_ah/warmup or /_ah/start) before it can handle external
          requests.

    Returns:
      The newly created instance.Instance.
    """
        def instance_config_getter():
            runtime_config = self._runtime_config_getter()
            runtime_config.instance_id = str(instance_id)
            return runtime_config

        def extra_args_getter(port):
            return 'jetty.port=%s' % port

        env = self._java_application.get_environment()
        runtime_config = instance_config_getter()
        for env_entry in runtime_config.environ:
            env[env_entry.key] = env_entry.value

        if self._for_jetty9:
            start_process_flavor = http_runtime.START_PROCESS_REVERSE_NO_FILE
            env['APP_ENGINE_LOG_CONFIG_PATTERN'] = (os.path.join(
                tempfile.mkdtemp(suffix='gae'), 'log.%g'))
        else:
            start_process_flavor = http_runtime.START_PROCESS_FILE

        with self._application_lock:
            proxy = http_runtime.HttpRuntimeProxy(
                self._java_command,
                instance_config_getter,
                self._module_configuration,
                env=env,
                start_process_flavor=start_process_flavor,
                extra_args_getter=extra_args_getter)

        return instance.Instance(self.request_data, instance_id, proxy,
                                 self.max_concurrent_requests,
                                 self.max_background_threads,
                                 expect_ready_request)
Beispiel #12
0
  def new_instance(self, instance_id, expect_ready_request=False):
    """Create and return a new Instance.

    Args:
      instance_id: A string or integer representing the unique (per module) id
          of the instance.
      expect_ready_request: If True then the instance will be sent a special
          request (i.e. /_ah/warmup or /_ah/start) before it can handle external
          requests.

    Returns:
      The newly created instance.Instance.
    """

    def instance_config_getter():
      runtime_config = self._GenerateConfigForRuntime()
      runtime_config.instance_id = str(instance_id)
      return runtime_config

    php_executable_path = (
        self._GenerateConfigForRuntime().php_config.php_executable_path)

    gae_extension_path = (
        self._GenerateConfigForRuntime().php_config.gae_extension_path)

    if php_executable_path not in self._php_binary_to_error_proxy:
      try:
        self._check_binaries(php_executable_path, gae_extension_path)
      except Exception as e:
        self._php_binary_to_error_proxy[php_executable_path] = (
            _BadPHPEnvironmentRuntimeProxy(php_executable_path, e))
        logging.exception('The PHP runtime is not available')
      else:
        self._php_binary_to_error_proxy[php_executable_path] = None

    proxy = self._php_binary_to_error_proxy[php_executable_path]
    if proxy is None:
      proxy = http_runtime.HttpRuntimeProxy(_RUNTIME_ARGS,
                                            instance_config_getter,
                                            self._module_configuration)
    return instance.Instance(self.request_data,
                             instance_id,
                             proxy,
                             self.max_concurrent_requests,
                             self.max_background_threads,
                             expect_ready_request)
Beispiel #13
0
 def test_handle_with_error_no_error_handler(self):
     self.proxy = http_runtime.HttpRuntimeProxy(['/runtime'],
                                                self.runtime_config_getter,
                                                appinfo.AppInfoExternal())
     self.proxy._port = 23456
     response = FakeHttpResponse(
         500, 'Internal Server Error',
         [(http_runtime_constants.ERROR_CODE_HEADER, '1')], '')
     login.get_user_info(None).AndReturn(('', False, ''))
     httplib.HTTPConnection.connect()
     httplib.HTTPConnection.request(
         'GET', '/get%20error', '', {
             'HEADER': 'value',
             http_runtime_constants.REQUEST_ID_HEADER: 'request id',
             'X-AppEngine-Country': 'ZZ',
             'X-Appengine-Internal-User-Email': '',
             'X-Appengine-Internal-User-Id': '',
             'X-Appengine-Internal-User-Is-Admin': '0',
             'X-Appengine-Internal-User-Nickname': '',
             'X-Appengine-Internal-User-Organization': '',
             'X-APPENGINE-INTERNAL-SCRIPT': 'get.py',
             'X-APPENGINE-INTERNAL-SERVER-NAME': 'localhost',
             'X-APPENGINE-INTERNAL-SERVER-PORT': '8080',
             'X-APPENGINE-INTERNAL-SERVER-PROTOCOL': 'HTTP/1.1',
         })
     httplib.HTTPConnection.getresponse().AndReturn(response)
     httplib.HTTPConnection.close()
     environ = {
         'HTTP_HEADER': 'value',
         'PATH_INFO': '/get error',
         'QUERY_STRING': '',
         'HTTP_X_APPENGINE_INTERNAL_USER_ID': '123',
         'SERVER_NAME': 'localhost',
         'SERVER_PORT': '8080',
         'SERVER_PROTOCOL': 'HTTP/1.1',
     }
     self.mox.ReplayAll()
     self.assertResponse('500 Internal Server Error', {},
                         '',
                         self.proxy.handle,
                         environ,
                         url_map=self.url_map,
                         match=re.match(self.url_map.url, '/get%20error'),
                         request_id='request id',
                         request_type=instance.NORMAL_REQUEST)
     self.mox.VerifyAll()
  def new_instance(self, instance_id, expect_ready_request=False):
    """Create and return a new Instance.

    Args:
      instance_id: A string or integer representing the unique (per server) id
          of the instance.
      expect_ready_request: If True then the instance will be sent a special
          request (i.e. /_ah/warmup or /_ah/start) before it can handle external
          requests.

    Returns:
      The newly created instance.Instance.
    """

    def instance_config_getter():
      runtime_config = self._runtime_config_getter()
      runtime_config.instance_id = str(instance_id)
      return runtime_config

    php_executable_path = (
        self._runtime_config_getter().php_config.php_executable_path)

    if self._php_binary_to_bad_environment_proxy.get(
        php_executable_path) is None:
      try:
        self._check_environment(php_executable_path)
      except _PHPEnvironmentError as e:
        self._php_binary_to_bad_environment_proxy[php_executable_path] = (
            _BadPHPEnvironmentRuntimeProxy(php_executable_path, str(e)))
        logging.error('The PHP runtime is not available because: %r', str(e))
      else:
        self._php_binary_to_bad_environment_proxy[php_executable_path] = None

    proxy = self._php_binary_to_bad_environment_proxy[php_executable_path]
    if proxy is None:
      proxy = http_runtime.HttpRuntimeProxy(_RUNTIME_ARGS,
                                            instance_config_getter,
                                            self._server_configuration)
    return instance.Instance(self.request_data,
                             instance_id,
                             proxy,
                             self.max_concurrent_requests,
                             self.max_background_threads,
                             expect_ready_request)
Beispiel #15
0
  def test_connection_error(self):
    self.proxy = http_runtime.HttpRuntimeProxy(
        ['/runtime'], self.runtime_config_getter, appinfo.AppInfoExternal())
    self.proxy._process = self.mox.CreateMockAnything()
    login.get_user_info(None).AndReturn(('', False, ''))
    httplib.HTTPConnection.connect().AndRaise(socket.error())
    self.proxy._process.poll().AndReturn(None)
    httplib.HTTPConnection.close()

    self.mox.ReplayAll()
    self.assertRaises(socket.error,
                      self.proxy.handle(
                          {'PATH_INFO': '/'},
                          start_response=None,  # Not used.
                          url_map=self.url_map,
                          match=re.match(self.url_map.url, '/get%20error'),
                          request_id='request id',
                          request_type=instance.NORMAL_REQUEST).next)
    self.mox.VerifyAll()
Beispiel #16
0
  def new_instance(self, instance_id, expect_ready_request=False):
    """Create and return a new Instance.

    Args:
      instance_id: A string or integer representing the unique (per module) id
          of the instance.
      expect_ready_request: If True then the instance will be sent a special
          request (i.e. /_ah/warmup or /_ah/start) before it can handle external
          requests.

    Returns:
      The newly created instance.Instance.
    """

    def instance_config_getter():
      runtime_config = self._runtime_config_getter()
      runtime_config.instance_id = str(instance_id)
      return runtime_config

    env = self._java_application.get_environment()
    instance_jar = os.path.abspath(os.path.join(
        os.path.dirname(google.__file__),
        'appengine/tools/devappserver2/java/lib/StandaloneInstance_deploy.jar'))
    assert os.path.exists(instance_jar), instance_jar
    # TODO: replace this with something smaller and releasable

    with self._application_lock:
      proxy = http_runtime.HttpRuntimeProxy(
          ['java', '-jar', instance_jar],
          instance_config_getter,
          self._module_configuration,
          env=env,
          start_process_flavor=http_runtime.START_PROCESS_FILE)

    return instance.Instance(self.request_data,
                             instance_id,
                             proxy,
                             self.max_concurrent_requests,
                             self.max_background_threads,
                             expect_ready_request)
Beispiel #17
0
    def new_instance(self, instance_id, expect_ready_request=False):
        """Create and return a new Instance.

    Args:
      instance_id: A string or integer representing the unique (per server) id
          of the instance.
      expect_ready_request: If True then the instance will be sent a special
          request (i.e. /_ah/warmup or /_ah/start) before it can handle external
          requests.

    Returns:
      The newly created instance.Instance.
    """
        def instance_config_getter():
            runtime_config = self._runtime_config_getter()
            runtime_config.instance_id = str(instance_id)
            return runtime_config

        with self._application_lock:
            try:
                self._go_application.maybe_build(
                    self._modified_since_last_build)
            except go_application.BuildError as e:
                logging.error('Failed to build Go application: %s', e)
                proxy = _GoBuildFailureRuntimeProxy(e)
            else:
                proxy = http_runtime.HttpRuntimeProxy(
                    self._go_application.go_executable, instance_config_getter,
                    self._server_configuration,
                    self._go_application.get_environment())
            self._modified_since_last_build = False

        return instance.Instance(self.request_data, instance_id, proxy,
                                 self.max_concurrent_requests,
                                 self.max_background_threads,
                                 expect_ready_request)
Beispiel #18
0
    def new_instance(self, instance_id, expect_ready_request=False):
        """Create and return a new Instance.

    Args:
      instance_id: A string or integer representing the unique (per module) id
          of the instance.
      expect_ready_request: If True then the instance will be sent a special
          request (i.e. /_ah/warmup or /_ah/start) before it can handle external
          requests.

    Returns:
      The newly created instance.Instance.
    """
        def instance_config_getter():
            runtime_config = self._runtime_config_getter()
            runtime_config.instance_id = str(instance_id)
            return runtime_config

        # Note, the PORT will be added to the environment when the HttpRuntimeProxy
        # is started.
        prefix_to_strip = 'dev~'
        app_id = self._module_configuration.application
        if app_id.startswith('dev~'):
            app_id = app_id[len(prefix_to_strip):]

        instance_start_time = datetime.datetime.now().strftime('%Y%m%dt%H%M%S')
        node_environ = {
            'GAE_ENV':
            'localdev',
            'GAE_INSTANCE':
            instance_id,
            'GAE_MEMORY_MB':
            str(self._module_configuration.memory_limit),
            'GAE_RUNTIME':
            self._module_configuration.runtime,
            'GAE_SERVICE':
            self._module_configuration.module_name,
            'GAE_VERSION': (self._module_configuration.major_version
                            or instance_start_time),
            # TODO: Determine how to pull the gcloud project from the
            # Cloud SDK.
            'GOOGLE_CLOUD_PROJECT':
            app_id,
        }

        # Set the runtime config environment variables to pass into the subprocess.
        for env_var in self._runtime_config_getter().environ:
            if env_var.key not in node_environ:
                # We don't allow users to override the standard runtime environment
                # variables. In production, no error is raised, and the standard runtime
                # environment variables take precendence over user-defined variables
                # of the same name.
                node_environ[env_var.key] = env_var.value

        proxy = http_runtime.HttpRuntimeProxy(
            _RUNTIME_ARGS,
            instance_config_getter,
            self._module_configuration,
            env=node_environ,
            start_process_flavor=http_runtime.START_PROCESS_REVERSE)
        return instance.Instance(self.request_data, instance_id, proxy,
                                 self.max_concurrent_requests,
                                 self.max_background_threads,
                                 expect_ready_request)