예제 #1
0
파일: tracing.py 프로젝트: zhengxle/buck
 def __enter__(self):
     now_us = monotonic_time_nanos() / 1000
     self._add_trace_event(
         "buck-launcher",
         self.name,
         _TraceEventPhases.BEGIN,
         self.pid,
         1,
         now_us,
         self.args,
     )
예제 #2
0
파일: tracing.py 프로젝트: zhengxle/buck
 def __exit__(self, x_type, x_value, x_traceback):
     now_us = monotonic_time_nanos() / 1000
     self._add_trace_event(
         "buck-launcher",
         self.name,
         _TraceEventPhases.END,
         self.pid,
         1,
         now_us,
         self.args,
     )
예제 #3
0
파일: buck_tool.py 프로젝트: zhengxle/buck
    def launch_buckd(self, java_path, jvm_args, buck_version_uid=None):
        with Tracing("BuckTool.launch_buckd"):
            setup_watchman_watch()
            if buck_version_uid is None:
                buck_version_uid = self._get_buck_version_uid()
            self._buck_project.create_buckd_dir()
            # Override self._tmp_dir to a long lived directory.
            buckd_tmp_dir = self._buck_project.create_buckd_tmp_dir()
            ngserver_output_path = os.path.join(buckd_tmp_dir, "ngserver-out")
            """
            Use SoftRefLRUPolicyMSPerMB for immediate GC of javac output.
            Set timeout to 60s (longer than the biggest GC pause seen for a 2GB
            heap) and GC target to 15s. This means that the GC has to miss its
            target by 100% or many 500ms heartbeats must be missed before a client
            disconnection occurs. Specify port 0 to allow Nailgun to find an
            available port, then parse the port number out of the first log entry.
            """
            command = ["buckd"]
            extra_default_options = [
                "-Dbuck.is_buckd=true",
                "-Dbuck.buckd_launch_time_nanos={0}".format(
                    monotonic_time_nanos()),
                "-Dfile.encoding=UTF-8",
                "-XX:MaxGCPauseMillis={0}".format(GC_MAX_PAUSE_TARGET),
                "-XX:SoftRefLRUPolicyMSPerMB=0",
                # Stop Java waking up every 50ms to collect thread
                # statistics; doing it once every five seconds is much
                # saner for a long-lived daemon.
                "-XX:PerfDataSamplingInterval=5000",
                # Do not touch most signals
                "-Xrs",
                # Likewise, waking up once per second just in case
                # there's some rebalancing to be done is silly.
                "-XX:+UnlockDiagnosticVMOptions",
                "-XX:GuaranteedSafepointInterval=5000",
                "-Djava.io.tmpdir={0}".format(buckd_tmp_dir),
                "-Dcom.facebook.nailgun.NGServer.outputPath={0}".format(
                    ngserver_output_path),
                "-XX:+UseG1GC",
                "-XX:MaxHeapFreeRatio=40",
            ]

            command.extend(extra_default_options)
            command.extend(jvm_args)
            command.append(
                "com.facebook.buck.cli.bootstrapper.ClassLoaderBootstrapper")
            command.append("com.facebook.buck.cli.BuckDaemon")
            command.append(self._buck_project.get_buckd_transport_address())
            command.append("{0}".format(BUCKD_CLIENT_TIMEOUT_MILLIS))

            buckd_transport_file_path = (
                self._buck_project.get_buckd_transport_file_path())
            if os.name == "nt":
                # https://msdn.microsoft.com/en-us/library/windows/desktop/ms684863.aspx#DETACHED_PROCESS
                DETACHED_PROCESS = 0x00000008
                creationflags = DETACHED_PROCESS
                # do not redirect output for Windows as it deadlocks
                stdin = None
                stdout = None
                stderr = None
                close_fds = True
            else:
                """
                Change the process group of the child buckd process so that when this
                script is interrupted, it does not kill buckd.
                """
                creationflags = 0
                stdin = open(os.devnull, mode="r")
                stdout = open(self._buck_project.get_buckd_stdout(),
                              mode="w+b",
                              buffering=0)
                stderr = open(self._buck_project.get_buckd_stderr(),
                              mode="w+b",
                              buffering=0)
                close_fds = False

            process = subprocess.Popen(
                command,
                executable=java_path,
                cwd=self._buck_project.root,
                env=self._environ_for_buck(),
                creationflags=creationflags,
                close_fds=close_fds,
                stdin=stdin,
                stdout=stdout,
                stderr=stderr,
            )

            self._buck_project.save_buckd_version(buck_version_uid)
            self._buck_project.save_buckd_jvm_args(
                self._get_java_args(buck_version_uid))

            # Give Java some time to create the listening socket.

            wait_seconds = 0.01
            repetitions = int(BUCKD_STARTUP_TIMEOUT_MILLIS / 1000.0 /
                              wait_seconds)
            for _idx in range(repetitions):
                if transport_exists(buckd_transport_file_path):
                    break
                time.sleep(wait_seconds)

            if not transport_exists(buckd_transport_file_path):
                return False

            returncode = process.poll()

            # If the process has exited then daemon failed to start
            if returncode is not None:
                return False

            # Save pid of running daemon
            self._buck_project.save_buckd_pid(process.pid)

            logging.info("Buck daemon started.")

            return True