Page MenuHomePhorge
Diviner libphutil Tech Docs ArcanistHgServerChannel

final class ArcanistHgServerChannel
libphutil Technical Documentation ()

Channel to a Mercurial "cmdserver" server. Messages sent to the server look like this:

runcommand\n
8                   # Length, as a 4-byte unsigned long.
log\0
-l\0
5

In PHP, the format of these messages is an array of arguments:

array(
  'runcommand',
  'log',
  '-l',
  '5',
);

The server replies with messages that look like this:

o
1234                # Length, as a 4-byte unsigned long.
<data: 1234 bytes>

The first character in a message from the server is the "channel". Mercurial channels have nothing to do with Phutil channels; they are more similar to stdout/stderr. Mercurial has four primary channels:

'o'utput, like stdout
'e'rror, like stderr
'r'esult, like return codes
'd'ebug, like an external log file

In PHP, the format of these messages is a pair, with the channel and then the data:

array('o', '<data...>');

In general, we send "runcommand" requests, and the server responds with a series of messages on the "output" channel and then a single response on the "result" channel to indicate that output is complete.

Tasks

Reading and Writing

  • public function read() — Read a message from the channel, if a message is available.
  • public function write($message) — Write a message to the channel.
  • public function addMessage($message) — Add a message to the queue. While you normally do not need to do this, you can use it to inject out-of-band messages.

Waiting for Activity

  • public static function waitForAny($channels, $options) — Wait for any activity on a list of channels. Convenience wrapper around @{method:waitForActivity}.
  • public static function waitForActivity($reads, $writes, $options) — Wait (using select()) for channels to become ready for reads or writes. This method blocks until some channel is ready to be updated.
  • public function waitForMessage() — Wait for a message, blocking until one is available.

Responding to Activity

Channel Implementation

Protocol Implementation

  • protected function encodeMessage($argv) — Encode a message for transmission to the server. The message should be formatted as an array, like this:
  • protected function decodeStream($data) — Decode a message received from the server. The message looks like this:

Other Methods

Methods

public function __get($name)
Inherited

This method is not documented.
Parameters
$name
Return
wild

public function __set($name, $value)
Inherited

This method is not documented.
Parameters
$name
$value
Return
wild

public function current()
Inherited

This method is not documented.
Return
wild

public function key()
Inherited

This method is not documented.
Return
wild

public function next()
Inherited

This method is not documented.
Return
wild

public function rewind()
Inherited

This method is not documented.
Return
wild

public function valid()
Inherited

This method is not documented.
Return
wild

private function throwOnAttemptedIteration()
Inherited

This method is not documented.
Return
wild

public function getPhobjectClassConstant($key, $byte_limit)
Inherited

Phobject

Read the value of a class constant.

This is the same as just typing self::CONSTANTNAME, but throws a more useful message if the constant is not defined and allows the constant to be limited to a maximum length.

Parameters
string$keyName of the constant.
int|null$byte_limitMaximum number of bytes permitted in the value.
Return
stringValue of the constant.

public function __construct($channel)
Inherited

This method is not documented.
Return
this//Implicit.//

public function read()
Inherited

PhutilChannel

Read from the channel. A channel defines the format of data that is read from it, so this method may return strings, objects, or anything else.

The default implementation returns bytes.

PhutilProtocolChannel

Read a message from the channel, if a message is available.

Return
wildA message, or null if no message is available.

public function write($message)
Inherited

PhutilChannel

Write to the channel. A channel defines what data format it accepts, so this method may take strings, objects, or anything else.

The default implementation accepts bytes.

PhutilProtocolChannel

Write a message to the channel.

Parameters
wild$bytesData to write to the channel, normally bytes.
Return
this

public static function waitForAny($channels, $options)
Inherited

PhutilChannel

Wait for any activity on a list of channels. Convenience wrapper around waitForActivity().

Parameters
list<PhutilChannel>$channelsA list of channels to wait for.
dict$optionsOptions, see above.
Return
void

public static function waitForActivity($reads, $writes, $options)
Inherited

PhutilChannel

Wait (using select()) for channels to become ready for reads or writes. This method blocks until some channel is ready to be updated.

It does not provide a way to determine which channels are ready to be updated. The expectation is that you'll just update every channel. This might change eventually.

Available options are:

  • 'read' (list<stream>) Additional streams to select for read.
  • 'write' (list<stream>) Additional streams to select for write.
  • 'except' (list<stream>) Additional streams to select for except.
  • 'timeout' (float) Select timeout, defaults to 1.
NOTE: Extra streams must be streams, not sockets, because this method uses stream_select(), not socket_select().
Parameters
list<PhutilChannel>$readsList of channels to wait for reads on.
list<PhutilChannel>$writesList of channels to wait for writes on.
array$options
Return
void

public function update()
Inherited

PhutilChannel

Updates the channel, filling input buffers and flushing output buffers. Returns false if the channel has closed.

Return
boolTrue if the channel is still open.

public function setName($name)
Inherited

PhutilChannel

Set a channel name. This is primarily intended to allow you to debug channel code more easily, by naming channels something meaningful.

Parameters
string$nameChannel name.
Return
this

public function getName()
Inherited

PhutilChannel

Get the channel name, as set by setName().

Return
stringName of the channel.

public function isOpen()
Inherited

PhutilChannel

Test if the channel is open: active, can be read from and written to, etc.

Return
boolTrue if the channel is open.

public function closeWriteChannel()
Inherited

PhutilChannel

Close the channel for writing.

Return
void

public function isOpenForReading()
Inherited

PhutilChannel

Test if the channel is open for reading.

Return
boolTrue if the channel is open for reading.

public function isOpenForWriting()
Inherited

PhutilChannel

Test if the channel is open for writing.

Return
boolTrue if the channel is open for writing.

protected function readBytes($length)
Inherited

PhutilChannel

Read from the channel's underlying I/O.

Parameters
int$lengthMaximum number of bytes to read.
Return
stringBytes, if available.

protected function writeBytes($bytes)
Inherited

PhutilChannel

Write to the channel's underlying I/O.

Parameters
string$bytesBytes to write.
Return
intNumber of bytes written.

protected function getReadSockets()
Inherited

PhutilChannel

Get sockets to select for reading.

Return
list<stream>Read sockets.

protected function getWriteSockets()
Inherited

PhutilChannel

Get sockets to select for writing.

Return
list<stream>Write sockets.

public function setReadBufferSize($size)
Inherited

PhutilChannel

Set the maximum size of the channel's read buffer. Reads will artificially block once the buffer reaches this size until the in-process buffer is consumed.

Parameters
int|null$sizeMaximum read buffer size, or `null` for a limitless buffer.
Return
this

public function isReadBufferEmpty()
Inherited

PhutilChannel

Test state of the read buffer.

Return
boolTrue if the read buffer is empty.

public function isWriteBufferEmpty()
Inherited

PhutilChannel

Test state of the write buffer.

Return
boolTrue if the write buffer is empty.

public function getWriteBufferSize()
Inherited

PhutilChannel

Get the number of bytes we're currently waiting to write.

Return
intNumber of waiting bytes.

public function flush()
Inherited

PhutilChannel

Wait for any buffered writes to complete. This is a blocking call. When the call returns, the write buffer will be empty.

Return
wild

protected function didConstruct()
Inherited

This method is not documented.
Return
wild

protected function getUnderlyingChannel()
Inherited

This method is not documented.
Return
wild

private function throwOnRawByteOperations()
Inherited

This method is not documented.
Return
wild

public function addMessage($message)
Inherited

PhutilProtocolChannel

Add a message to the queue. While you normally do not need to do this, you can use it to inject out-of-band messages.

Parameters
wild$messageSome message.
Return
this

protected function encodeMessage($argv)

PhutilProtocolChannel

Encode a message for transmission.

ArcanistHgServerChannel

Encode a message for transmission to the server. The message should be formatted as an array, like this:

array(
  'runcommand',
  'log',
  '-l',
  '5',
);

We will return the cmdserver version of this:

runcommand\n
8                   # Length, as a 4-byte unsigned long.
log\0
-l\0
5
Parameters
wild$messageSome message.
Return
stringEncoded string for transmission to the server.

protected function decodeStream($data)

PhutilProtocolChannel

Decode bytes from the underlying channel into zero or more complete messages. The messages should be returned.

This method is called as data is available. It will receive incoming data only once, and must buffer any data which represents only part of a message. Once a complete message is received, it can return the message and discard that part of the buffer.

Generally, a protocol channel should maintain a read buffer, implement a parser in this method, and store parser state on the object to be able to process incoming data in small chunks.

ArcanistHgServerChannel

Decode a message received from the server. The message looks like this:

o
1234                # Length, as a 4-byte unsigned long.
<data: 1234 bytes>

...where 'o' is the "channel" the message is being sent over.

We decode into a pair in PHP, which looks like this:

array('o', '<data...>');
Parameters
string$dataOne or more bytes from the underlying channel.
Return
list<pair<string,string>>Zero or more complete messages.

public function waitForMessage()
Inherited

PhutilProtocolChannel

Wait for a message, blocking until one is available.

Return
wildA message.