Correct Aphlict websocket URI construction after PHP8 compatibility changes
[phabricator.git] / src / applications / diffusion / ssh / DiffusionGitReceivePackSSHWorkflow.php
blobf59a9b58b4d8c5b331cad301c3cd07e964460b95
1 <?php
3 final class DiffusionGitReceivePackSSHWorkflow extends DiffusionGitSSHWorkflow {
5 protected function didConstruct() {
6 $this->setName('git-receive-pack');
7 $this->setArguments(
8 array(
9 array(
10 'name' => 'dir',
11 'wildcard' => true,
13 ));
16 protected function executeRepositoryOperations() {
17 // This is a write, and must have write access.
18 $this->requireWriteAccess();
20 $is_proxy = $this->shouldProxy();
21 if ($is_proxy) {
22 return $this->executeRepositoryProxyOperations($for_write = true);
25 $host_wait_start = microtime(true);
27 $repository = $this->getRepository();
28 $viewer = $this->getSSHUser();
29 $device = AlmanacKeys::getLiveDevice();
31 $cluster_engine = id(new DiffusionRepositoryClusterEngine())
32 ->setViewer($viewer)
33 ->setRepository($repository)
34 ->setLog($this);
36 $command = csprintf('git-receive-pack %s', $repository->getLocalPath());
37 $cluster_engine->synchronizeWorkingCopyBeforeWrite();
39 if ($device) {
40 $this->writeClusterEngineLogMessage(
41 pht(
42 "# Ready to receive on cluster host \"%s\".\n",
43 $device->getName()));
46 $log = $this->newProtocolLog($is_proxy);
47 if ($log) {
48 $this->setProtocolLog($log);
49 $log->didStartSession($command);
52 $caught = null;
53 try {
54 $err = $this->executeRepositoryCommand($command);
55 } catch (Exception $ex) {
56 $caught = $ex;
59 if ($log) {
60 $log->didEndSession();
63 // We've committed the write (or rejected it), so we can release the lock
64 // without waiting for the client to receive the acknowledgement.
65 $cluster_engine->synchronizeWorkingCopyAfterWrite();
67 if ($caught) {
68 throw $caught;
71 if (!$err) {
72 $this->waitForGitClient();
74 // When a repository is clustered, we reach this cleanup code on both
75 // the proxy and the actual final endpoint node. Don't do more cleanup
76 // or logging than we need to.
77 $repository->writeStatusMessage(
78 PhabricatorRepositoryStatusMessage::TYPE_NEEDS_UPDATE,
79 PhabricatorRepositoryStatusMessage::CODE_OKAY);
81 $host_wait_end = microtime(true);
83 $this->updatePushLogWithTimingInformation(
84 $this->getClusterEngineLogProperty('writeWait'),
85 $this->getClusterEngineLogProperty('readWait'),
86 ($host_wait_end - $host_wait_start));
89 return $err;
92 private function executeRepositoryCommand($command) {
93 $repository = $this->getRepository();
94 $command = PhabricatorDaemon::sudoCommandAsDaemonUser($command);
96 $future = id(new ExecFuture('%C', $command))
97 ->setEnv($this->getEnvironment());
99 return $this->newPassthruCommand()
100 ->setIOChannel($this->getIOChannel())
101 ->setCommandChannelFromExecFuture($future)
102 ->execute();
105 private function updatePushLogWithTimingInformation(
106 $write_wait,
107 $read_wait,
108 $host_wait) {
110 if ($write_wait !== null) {
111 $write_wait = (int)(1000000 * $write_wait);
114 if ($read_wait !== null) {
115 $read_wait = (int)(1000000 * $read_wait);
118 if ($host_wait !== null) {
119 $host_wait = (int)(1000000 * $host_wait);
122 $identifier = $this->getRequestIdentifier();
124 $event = new PhabricatorRepositoryPushEvent();
125 $conn = $event->establishConnection('w');
127 queryfx(
128 $conn,
129 'UPDATE %T SET writeWait = %nd, readWait = %nd, hostWait = %nd
130 WHERE requestIdentifier = %s',
131 $event->getTableName(),
132 $write_wait,
133 $read_wait,
134 $host_wait,
135 $identifier);