Page MenuHomePhorge
Diviner libphutil Tech Docs ArcanistHgClientChannel

final class ArcanistHgClientChannel
libphutil Technical Documentation ()

Channel to a Mercurial "cmdserver" client. For a detailed description of the "cmdserver" protocol, see ArcanistHgServerChannel. This channel implements the other half of the protocol: it decodes messages from the client and encodes messages from the server.

Because the proxy server speaks the exact same protocol that Mercurial does and fully decodes both sides of the protocol, we need this half of the decode/encode to talk to clients. Without it, we wouldn't be able to determine when a client request had completed and was ready for transmission to the Mercurial server.

(Technically, we could get away without re-encoding messages from the server, but the serialization is not complicated and having a general implementation of encoded/decode for both the client and server dialects seemed useful.)

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 client. The message should be a pair with the channel name and the a block of data, like this:
  • protected function decodeStream($data) — Decode a message received from the client. 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.

ArcanistHgClientChannel

Encode a message for transmission to the client. The message should be a pair with the channel name and the a block of data, like this:

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

We encode it like this:

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

For a detailed description of the cmdserver protocol, see ArcanistHgServerChannel.

Parameters
wild$messageSome message.
Return
stringEncoded string for transmission to the client.

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.

ArcanistHgClientChannel

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

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

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

array(
  'runcommand',
  'log',
  '-l',
  '5',
);
Parameters
string$dataOne or more bytes from the underlying channel.
Return
list<list<string>>Zero or more complete commands.

public function waitForMessage()
Inherited

PhutilProtocolChannel

Wait for a message, blocking until one is available.

Return
wildA message.