mirror of
https://github.com/vczh-libraries/Release.git
synced 2026-08-17 09:21:41 +08:00
Sync coding agent context
This commit is contained in:
@@ -123,7 +123,7 @@ Protocol types are code-generated from `Protocol/*.txt` files into `GuiRemotePro
|
||||
|
||||
Two projects in `Test/GacUISrc/` demonstrate a full remote protocol deployment. They are paired: one is the core side (console application) and the other is the renderer side (Windows application).
|
||||
|
||||
RemoteViewModelTest-specific remoting support is organized in `Test/RemotingHelpers/Rvmt/`. `ViewModelShared.*` owns the fixed RVM constants and concrete generated-RPC dispatcher initialization, `ViewModelHostClient.*` owns only the network host client, and `ViewModelHostServer.*` owns the protected `RpcServerHelpers` implementation and the application-facing `RemoteViewModelChannelServer<TServerBase>`. The consolidated `Source_RemotingHelpers.vcxitems` inventory lists these files under its `Rvmt` filter and is imported only by remoting applications; standalone applications receive reusable automation endpoints through GacUI Core instead.
|
||||
Remote-view-model remoting support is organized in `Test/RemotingHelpers/Rvmt/`. `ViewModelShared.h` owns only generic channel aliases, fixed RVM constants, and inline Ready-message helpers; `ViewModelHostClient.*` owns the generic network host client; and `ViewModelHostServer.*` owns the protected generic `RpcServerHelpers` implementation and the application-facing `RemoteViewModelChannelServer<TServerBase>`. Concrete generated-RPC composition lives instead in `Generated_RemoteViewModelTest/RemoteViewModelTestInitialize.*` and is invoked directly by each consuming application. The consolidated `Source_RemotingHelpers.vcxitems` inventory lists only generic helpers under its `Rvmt` filter and is imported only by remoting applications; standalone applications receive reusable automation endpoints through GacUI Core instead.
|
||||
|
||||
### RemotingTest_Core (Console Application)
|
||||
|
||||
@@ -134,7 +134,7 @@ Located at `Test/GacUISrc/RemotingTest_Core/`. Accepts `/Pipe` or `/Http` argume
|
||||
2. The shared run function starts the server, creates a local core client with `GuiRemoteProtocolLocalChannelClient`, and connects it to the server. Local clients are accepted directly because only the owning process can call `ConnectLocalClient`.
|
||||
3. It wraps the core client's protocol channel in `GuiRemoteProtocolAsyncJsonChannel` and creates `SwitchableRenderersCoreChannel<TServerBase>`. This `GuiRemoteProtocolCoreChannel` subclass verifies at submission time that its protocol renderer is still the transport server's current renderer. `Submit` evaluates this virtual guard before applying the base channel's default no-renderer behavior, so the switchable channel can report disconnection for both a stale renderer and renderer id `-1` while the default channel still treats `-1` as an idle state.
|
||||
4. It builds `GuiRemoteProtocolFilter` -> `GuiRemoteProtocolDomDiffConverter` -> `SetupRemoteNativeController`. The Core remains usable before a renderer connects.
|
||||
5. In `/RVMT`, the shared server owns the requester session. The exact RVM host is admitted before service acquisition, while renderer admission remains closed until the requester enters its running phase after the window is constructed.
|
||||
5. In `/RVMT`, the shared server owns the requester session. The application calls `Connect` once with the complete required-service-name list, initializes generated RPC objects with the exposed generic dispatcher and assigned client ID, then calls repeatable `RequestService`. The exact RVM host is admitted before service acquisition, while renderer admission remains closed until the first service acquisition moves the requester into its running phase.
|
||||
6. On shutdown, Core clears the server's stored JSON/protocol channel pointers, finalizes the optional requester session, and stops the channel server before stack-owned wrappers are destroyed.
|
||||
|
||||
`RemotingChannelServer<TServerBase>::OnRemoteClientConnected` accepts replacement renderers. If a different renderer is already current, it calls `GuiRemoteProtocolCoreChannel::DetachRenderer(oldClientId)`, tries to send a raw `ControllerConnectionStopped` package to the old renderer, and disconnects the old transport only when notification fails. `RemoteViewModelChannelServer<TServerBase>` overrides this single remote-admission operation to accept the RVM host and to check the concrete requester phase before delegating renderer admission. If the RVM host disconnects, it broadcasts the business error when renderers are enabled and then terminates the requester.
|
||||
|
||||
@@ -188,7 +188,7 @@ channels[L"Events"]->BroadcastFromClient(package);
|
||||
channels[L"Events"]->BatchWrite(disconnected);
|
||||
```
|
||||
|
||||
The derived client can also handle `OnConnected`, `OnDisconnected`, `OnReadError` and `OnLocalError`. A raw protocol callback returns `true` from `INetworkProtocolCallback::OnLocalError` when it needs to promote a recoverable transport error to fatal; the protocol then stops only after the callback returns. `NetworkProtocolChannelClient` uses this hook after its channel reaches `Connected`: it reports every local error to its `IChannelClient` user with `fatal == true`, transitions the channel to disconnected, and asks the raw transport to stop. Before the channel is connected, raw retry policy remains in control.
|
||||
The derived client can also handle `OnConnected`, `OnDisconnected`, `OnReadError` and `OnLocalError`. A raw protocol callback returns `true` from `INetworkProtocolCallback::OnLocalError` when it needs to promote a recoverable transport error to fatal; the protocol then stops only after the callback returns. `NetworkProtocolChannelClient` uses this hook after its channel reaches `Connected`: it reports every local error to its `IChannelClient` user with `fatal == true`, transitions the channel to disconnected, and asks the raw transport to stop. `NetworkProtocolChannelServer` likewise promotes a server response-delivery error after that connection has been admitted, because the accepted channel can no longer guarantee delivery. Before either channel boundary is reached, raw retry policy remains in control.
|
||||
|
||||
`IChannelServer<TPackage>` routes messages but is not itself a channel participant. When server-side code must send ordinary channel messages, connect a `NetworkProtocolLocalChannelClient<TPackage, TSerialization>` with `ConnectLocalClient`; this gives the local participant a normal positive client id.
|
||||
|
||||
@@ -222,7 +222,7 @@ These helpers let another implementation reproduce the established wire facts wi
|
||||
|
||||
The client uses two physical `async_tcp_socket::SocketHttpClientApi` lanes for one logical token. One lane keeps the receive poll alive; the other serializes connection control and client sends. Replacing a failed physical lane does not replace the logical `INetworkProtocolConnection` unless the transport reports final disconnection.
|
||||
|
||||
The server maps the token to its logical connection, queues server messages when no receive request is available, and dispatches client messages through `INetworkProtocolCallback::OnReadString`. The channel bridge above this layer is unaware of the HTTP routes and physical lanes.
|
||||
The server maps the token to its logical connection, queues server messages when no receive request is available, and dispatches client messages through `INetworkProtocolCallback::OnReadString`. A successful nonempty `/Request` response starts a five-second acknowledgement deadline. The client submits its replacement `/Request` before delivering the message to its callback, and that replacement is the implicit acknowledgement that cancels the deadline. If the response cannot be delivered, the server first restores its message to the FIFO head; if the replacement poll does not arrive in time, the server treats the logical connection as lost. Both cases report a nonfatal local error. A raw callback may decline promotion, while an admitted `NetworkProtocolChannelServer` connection promotes the error, stops, unregisters the token and causes any late `/Request` carrying that token to receive 404. There is no heartbeat or explicit disconnect exchange, so an idle HTTP peer loss remains unknown until the server first attempts to deliver a message.
|
||||
|
||||
## Starting on Windows, Linux and macOS
|
||||
|
||||
|
||||
@@ -11,16 +11,16 @@ The reusable JSON RPC setup lives in `Source/Library/RpcJson`. User code normall
|
||||
- Create one `RpcJsonDispatcher(clientId, messageDispatcher)` and one `RpcJsonLifecycle(clientId, dispatcher)` per RPC endpoint. The `clientId` must be the endpoint id assigned by the transport.
|
||||
- Configure the lifecycle from generated RPC code before calling `Initialize()`: set the generated id map, pass the generated JSON serializer, JSON object ops, JSON object event ops, type-id callback, and event-attacher callback to `RpcJsonLifecycle::Register`, and register the generated wrapper factory.
|
||||
- Register local services with `IRpcLifecycle::RegisterLocalService(typeId, service)` before lifecycle initialization. Remote services are discovered through service declaration messages and can be requested by type name after initialization.
|
||||
- Use `RpcJsonDispatcherClientForTaskQueue` for endpoint-side channel IO when a single `TaskQueue` should process incoming RPC requests. A small generated-app wrapper should derive from it, call `SetRpcObjects`, and expose an app-specific `InitializeRpc(clientId)` function.
|
||||
- Use `RpcJsonDispatcherClientForTaskQueue` for endpoint-side channel IO when a single `TaskQueue` should process incoming RPC requests. Keep it generic and let an app-specific setup function receive `RpcJsonDispatcherClient*` plus the assigned `clientId`, construct the generated dispatcher/lifecycle objects, and call the public `SetRpcObjects` operation.
|
||||
- Use `RpcJsonDispatcherServerForTaskQueue` for the transport coordinator. It is not a service owner; it tracks connected client ids, forwards broadcast requests, caches service declarations, and consolidates broadcast responses.
|
||||
- Pass required remote service type names to `WaitForServer` or `ConnectLocalServer` so client initialization waits until those services have been declared.
|
||||
- Call `FinalizeRpc()` on endpoint dispatchers before shutting down the transport or unloading generated Workflow context.
|
||||
|
||||
An application-specific dispatcher wrapper normally derives from `RpcJsonDispatcherClientForTaskQueue`, creates the dispatcher/lifecycle pair after the transport assigns a client id, wires generated JSON serializer and ops into the lifecycle, registers the generated wrapper factory, and leaves transport behavior to `Source/Library/RpcJson`.
|
||||
An application-specific setup function normally receives a generic `RpcJsonDispatcherClient` after the transport assigns a client id, creates the dispatcher/lifecycle pair, wires generated JSON serializer and ops into the lifecycle, registers the generated wrapper factory, and leaves transport behavior to `Source/Library/RpcJson`. Derive a dispatcher subclass only to customize genuine dispatcher behavior such as task scheduling, not merely to reach RPC-object setup.
|
||||
|
||||
### Setup from Workflow Generated Code
|
||||
|
||||
Generated Workflow code is the only source of RPC-specific setup data. After the transport assigns `clientId`, the application-specific dispatcher wrapper creates `RpcJsonDispatcher(clientId, messageDispatcher)` and `RpcJsonLifecycle(clientId, rpcDispatcher.Obj())`, then stores them with `SetRpcObjects`.
|
||||
Generated Workflow code is the only source of RPC-specific setup data. After the transport assigns `clientId`, the application-specific setup function creates `RpcJsonDispatcher(clientId, messageDispatcher)` and `RpcJsonLifecycle(clientId, rpcDispatcher.Obj())`, then stores them through the message dispatcher's public `SetRpcObjects` operation.
|
||||
|
||||
The lifecycle id map comes from generated Workflow code. Setup calls `rpc_GetIds()`, converts the result to `Dictionary<WString, vint>` when crossing the C++ reflection boundary, and passes it to `RpcJsonLifecycle::SetIdMap`. Service-owning code resolves a full RPC interface name through `GetTypeIdFromName(fullName)` or reads the same id from `rpc_GetIds()[fullName]`, then calls `RegisterLocalService(typeId, service)` before lifecycle initialization.
|
||||
|
||||
@@ -35,7 +35,7 @@ Generated JSON operations are created once per lifecycle:
|
||||
|
||||
The wrapper factory is also generated-code based. `RegisterWrapperFactory` installs a callback that calls generated `rpcwrapper_Create(ref, lc, ops)`. `rpcwrapper_Create` returns a generated wrapper for a remote `RpcObjectReference`, and the same generated wrapper class is used for JSON transport because the JSON caller-side ops object is the `ops` argument passed into the wrapper.
|
||||
|
||||
Endpoint startup then happens through the reusable dispatcher client. A network endpoint calls `WaitForServer(channelClient, rpcChannel, waitingForServices)`, or a local endpoint calls `ConnectLocalServer(channelServer, localClient, rpcChannel, waitingForServices)`. When the channel reports `OnConnected(clientId)`, the application-specific wrapper performs the generated setup described above and then calls `Initialize()`. Client code requests a service with `GetRpcLifecycle()->RequestService(fullName)`; when the service is remote, the lifecycle returns the generated wrapper created by the registered factory, and ordinary interface method calls on that wrapper go through the generated JSON caller-side ops.
|
||||
Endpoint startup then happens through the reusable dispatcher client. A network endpoint calls `WaitForServer(channelClient, rpcChannel, waitingForServices)`, or a local endpoint calls `ConnectLocalServer(channelServer, localClient, rpcChannel, waitingForServices)`. After that operation supplies the assigned client id, application code performs the generated setup described above and then calls `Initialize()`. Client code requests a service with `GetRpcLifecycle()->RequestService(fullName)`; when the service is remote, the lifecycle returns the generated wrapper created by the registered factory, and ordinary interface method calls on that wrapper go through the generated JSON caller-side ops.
|
||||
|
||||
### Implementation
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
- Port fixes from imports to source repositories [14]
|
||||
- Proactively remove code made redundant by refactoring [14]
|
||||
- Keep design documentation aligned with code after refactoring [12]
|
||||
- Fix behavior at the owning state instead of patching symptoms [10]
|
||||
- Fix behavior at the owning state instead of patching symptoms [11]
|
||||
- Extract abstractions only for real shared behavior [9]
|
||||
- Verify and localize portability on every target OS [7]
|
||||
- Make `Stop()` drain asynchronous work before returning [6]
|
||||
@@ -307,6 +307,8 @@ When shared code and tests pass on other platforms but fail on one target, fix t
|
||||
|
||||
When a layered transport needs a stricter response policy than its general parser, enforce that policy in the object that owns the physical connection. Keep the lower parser reusable, and let the connection owner classify the response, report a structured failure, and stop or retry the transport as appropriate.
|
||||
|
||||
When HTTP long-poll delivery needs a bounded acknowledgement, put the deadline on the transport's acknowledgement transition instead of adding a timeout to a transport-independent RPC response wait. A locally successful response submission does not prove peer receipt. Arm the deadline only after delivering a nonempty server message, use the client's replacement poll as the implicit acknowledgement, cancel the deadline when that poll arrives, and report expiry through the transport's local-error path. Keep idle long polls unbounded when the protocol intentionally has no heartbeat.
|
||||
|
||||
## Treat environment correlation as evidence, not a cause
|
||||
|
||||
When a bug reproduces on one machine but not another, do not assume hardware speed or timing is causal merely because the machines differ. Reproduce the smallest differing state or response shape deterministically, then identify the missing transition or dependency that the other environment happens to mask.
|
||||
|
||||
@@ -238,7 +238,7 @@ SocketHttpClient(
|
||||
|
||||
The server adapter uses the injected listener and never creates another one. The client uses the injected client for its first physical lane and calls **CreateSameEndpointClient** for the additional lanes required by full-duplex polling and recovery. The server name must select loopback, and the URL prefix is empty for the origin root or begins with **/**.
|
||||
|
||||
The adapter uses the same **/VlppInterProcess/Connect**, **/VlppInterProcess/Request/{token}** and **/VlppInterProcess/Response/{token}** routes as **windows_http::HttpServer** and **windows_http::HttpClient**. The protocol has no message-level delivery acknowledgement, deduplication, heartbeat or disconnect route, so it must not be treated as exactly-once delivery.
|
||||
The adapter uses the same **/VlppInterProcess/Connect**, **/VlppInterProcess/Request/{token}** and **/VlppInterProcess/Response/{token}** routes as **windows_http::HttpServer** and **windows_http::HttpClient**. A successful nonempty Request response is provisional delivery: the next Request for the same token is its implicit acknowledgement and must arrive within five seconds. The deadline starts only when the server actually sends a message, so an idle connection has no heartbeat deadline. If the response fails, the server restores the message to the FIFO head; if the acknowledgement is missing, it reports a nonfatal local error. A raw callback may decline promotion, while an admitted **NetworkProtocolChannelServer** connection promotes either error, disconnects, unregisters the token and rejects any late Request carrying that stale token. The protocol still has no deduplication, heartbeat or explicit disconnect route and must not be treated as exactly-once delivery.
|
||||
|
||||
### Portable Mini HTTP Request Helpers
|
||||
|
||||
@@ -269,7 +269,7 @@ The raw HTTP protocol uses these routes under the configured base URL:
|
||||
|
||||
**vl::inter_process::windows_http::HttpClient::WaitForServer** sends the connect request, validates the returned URLs, records them and reports connection. **BeginReadingLoopUnsafe** starts the long-poll request loop. **SendString** posts to the response URL. Each recoverable failed Connect, Request or Response exchange calls **INetworkProtocolCallback::OnLocalError** with **fatal == false** before retrying; Connect and Response retry a limited number of times, while Request retries while the client is still running. Bounded retry exhaustion remains raw-fatal. Returning **true** from **OnLocalError** promotes a recoverable failure and makes the raw client stop after the callback returns. **NetworkProtocolChannelClient** does this for every local error after its channel reaches **Connected**, forwards **fatal == true** to its **IChannelClient** user and disconnects the channel; pre-handshake Connect retries remain under raw-client policy.
|
||||
|
||||
**vl::inter_process::windows_http::HttpServer** creates a **vl::inter_process::windows_http::HttpServerConnection** for each connect request. Server-to-client messages are returned through a pending long-poll request when possible, or queued until the next request. Client-to-server request bodies are dispatched as inbound strings. When the server stops, pending long-poll requests are cancelled and connection callbacks receive disconnection.
|
||||
**vl::inter_process::windows_http::HttpServer** creates a **vl::inter_process::windows_http::HttpServerConnection** for each connect request. Server-to-client messages are returned through a pending long-poll request when possible, or queued until the next request. A successful message response starts a five-second acknowledgement deadline; the next Request for the same GUID cancels it. A failed response retains the message, while a missing acknowledgement reports a recoverable **OnLocalError**. An admitted channel promotes either error, stops the logical connection and unregisters the GUID, so a late Request is rejected as unknown. No deadline runs while the server is idle. Client-to-server request bodies are dispatched as inbound strings. When the server stops, pending long-poll requests are cancelled and connection callbacks receive disconnection.
|
||||
|
||||
### Windows HTTP Helper APIs
|
||||
|
||||
|
||||
@@ -178,29 +178,22 @@ using JsonRpcLocalClient = JsonRpcChannelClient<JsonLocalChannelClient>;
|
||||
|
||||
## Endpoint Dispatcher Client
|
||||
|
||||
RpcJsonDispatcherClientForTaskQueue already implements IRpcJsonMessageDispatcher by sending JSON packages through a JsonChannel. A project still needs a small subclass to create RpcJsonDispatcher and RpcJsonLifecycle, then register the RPC metadata and helper operations for the loaded module.
|
||||
RpcJsonDispatcherClientForTaskQueue already implements IRpcJsonMessageDispatcher by sending JSON packages through a JsonChannel. Keep this transport dispatcher generic. After connection assigns a client id, pass the dispatcher and id to a module-specific setup function that creates RpcJsonDispatcher and RpcJsonLifecycle, then registers the RPC metadata and helper operations for the loaded module.
|
||||
|
||||
The module-specific registration is represented below by ConfigureLifecycleForRpcModule. It should set the id map, serializer, object ops, event ops, event attachers and wrapper factory for the module being used.
|
||||
```C++
|
||||
void ConfigureLifecycleForRpcModule(RpcJsonLifecycle* lifecycle);
|
||||
|
||||
class MyRpcDispatcherClient : public RpcJsonDispatcherClientForTaskQueue
|
||||
void InitializeRpcForModule(
|
||||
RpcJsonDispatcherClient* dispatcher,
|
||||
vint clientId)
|
||||
{
|
||||
public:
|
||||
MyRpcDispatcherClient(Ptr<TaskQueue> taskQueue)
|
||||
: RpcJsonDispatcherClientForTaskQueue(taskQueue)
|
||||
{
|
||||
}
|
||||
auto rpcDispatcher = Ptr(new RpcJsonDispatcher(clientId, dispatcher));
|
||||
auto lifecycle = Ptr(new RpcJsonLifecycle(clientId, rpcDispatcher.Obj()));
|
||||
|
||||
void InitializeRpc(vint clientId)
|
||||
{
|
||||
auto rpcDispatcher = Ptr(new RpcJsonDispatcher(clientId, this));
|
||||
auto lifecycle = Ptr(new RpcJsonLifecycle(clientId, rpcDispatcher.Obj()));
|
||||
|
||||
SetRpcObjects(rpcDispatcher, lifecycle);
|
||||
ConfigureLifecycleForRpcModule(lifecycle.Obj());
|
||||
}
|
||||
};
|
||||
dispatcher->SetRpcObjects(rpcDispatcher, lifecycle);
|
||||
ConfigureLifecycleForRpcModule(lifecycle.Obj());
|
||||
}
|
||||
```
|
||||
|
||||
## Server Channel Setup
|
||||
@@ -307,7 +300,7 @@ A process can host services through a local channel client connected to the same
|
||||
class JsonRpcServiceLocalClient : public JsonRpcLocalClient
|
||||
{
|
||||
private:
|
||||
Ptr<MyRpcDispatcherClient> dispatcher;
|
||||
Ptr<RpcJsonDispatcherClientForTaskQueue> dispatcher;
|
||||
|
||||
public:
|
||||
JsonRpcServiceLocalClient(Ptr<Parser> parser)
|
||||
@@ -315,12 +308,6 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
void OnConnected(vint clientId) override
|
||||
{
|
||||
CHECK_ERROR(dispatcher, L"The RPC dispatcher client is missing.");
|
||||
dispatcher->InitializeRpc(clientId);
|
||||
}
|
||||
|
||||
vint Connect(
|
||||
JsonChannelServer* channelServer,
|
||||
Ptr<JsonChannelClient> self,
|
||||
@@ -328,7 +315,7 @@ public:
|
||||
vint serverClientId,
|
||||
const List<WString>& waitingForServices)
|
||||
{
|
||||
dispatcher = Ptr(new MyRpcDispatcherClient(taskQueue));
|
||||
dispatcher = Ptr(new RpcJsonDispatcherClientForTaskQueue(taskQueue));
|
||||
auto clientId = dispatcher->ConnectLocalServer(
|
||||
channelServer,
|
||||
self,
|
||||
@@ -339,7 +326,7 @@ public:
|
||||
return clientId;
|
||||
}
|
||||
|
||||
MyRpcDispatcherClient* GetDispatcher()
|
||||
RpcJsonDispatcherClient* GetDispatcher()
|
||||
{
|
||||
CHECK_ERROR(dispatcher, L"The RPC dispatcher client is not connected.");
|
||||
return dispatcher.Obj();
|
||||
@@ -355,7 +342,7 @@ void HostLocalService(
|
||||
{
|
||||
auto serviceClient = Ptr(new JsonRpcServiceLocalClient(parser));
|
||||
List<WString> waitingForServices;
|
||||
serviceClient->Connect(
|
||||
auto clientId = serviceClient->Connect(
|
||||
channelServer,
|
||||
serviceClient,
|
||||
taskQueue,
|
||||
@@ -363,6 +350,7 @@ void HostLocalService(
|
||||
waitingForServices);
|
||||
|
||||
auto rpcClient = serviceClient->GetDispatcher();
|
||||
InitializeRpcForModule(rpcClient, clientId);
|
||||
auto lifecycle = rpcClient->GetRpcLifecycle();
|
||||
auto typeId = lifecycle->GetTypeIdFromName(L"example::IExampleService");
|
||||
CHECK_ERROR(typeId != RpcTypeId_NotFound, L"Unknown RPC service type.");
|
||||
@@ -378,40 +366,34 @@ A remote client uses JsonNetworkChannelClient over a raw transport such as **vl:
|
||||
```C++
|
||||
class JsonRpcNetworkEndpoint : public JsonRpcNetworkClient
|
||||
{
|
||||
private:
|
||||
Ptr<MyRpcDispatcherClient> dispatcher;
|
||||
|
||||
public:
|
||||
JsonRpcNetworkEndpoint(
|
||||
Ptr<MyRpcDispatcherClient> _dispatcher,
|
||||
Ptr<INetworkProtocolClient> transport,
|
||||
Ptr<Parser> parser)
|
||||
: JsonRpcNetworkClient(transport, parser)
|
||||
, dispatcher(_dispatcher)
|
||||
{
|
||||
}
|
||||
|
||||
void OnConnected(vint clientId) override
|
||||
void OnConnected(vint) override
|
||||
{
|
||||
CHECK_ERROR(dispatcher, L"The RPC dispatcher client is missing.");
|
||||
dispatcher->InitializeRpc(clientId);
|
||||
}
|
||||
};
|
||||
|
||||
Ptr<MyRpcDispatcherClient> ConnectRemoteRpcClient(
|
||||
Ptr<RpcJsonDispatcherClientForTaskQueue> ConnectRemoteRpcClient(
|
||||
Ptr<Parser> parser,
|
||||
Ptr<TaskQueue> taskQueue,
|
||||
const List<WString>& waitingForServices)
|
||||
{
|
||||
auto dispatcher = Ptr(new MyRpcDispatcherClient(taskQueue));
|
||||
auto dispatcher = Ptr(new RpcJsonDispatcherClientForTaskQueue(taskQueue));
|
||||
auto transport = Ptr(new named_pipe::NamedPipeClient(L"WorkflowRpcPipe"));
|
||||
auto channelClient = Ptr(new JsonRpcNetworkEndpoint(dispatcher, transport, parser));
|
||||
auto channelClient = Ptr(new JsonRpcNetworkEndpoint(transport, parser));
|
||||
|
||||
dispatcher->WaitForServer(
|
||||
channelClient.Obj(),
|
||||
channelClient->GetRpcChannel(),
|
||||
waitingForServices);
|
||||
|
||||
InitializeRpcForModule(dispatcher.Obj(), channelClient->GetClientId());
|
||||
dispatcher->Initialize();
|
||||
return dispatcher;
|
||||
}
|
||||
|
||||
@@ -12,6 +12,9 @@
|
||||
- You are not allowed to modify any source code, unless directly instructed in answers to review comments.
|
||||
- You are not going to execute the task, you are just reviewing it.
|
||||
- If everything just looks good, you do not have to make any change to the task file.
|
||||
- You are not allowed to change my original words in this file:
|
||||
- `## DETAILS`, `## VERIFICATION` and `## REVIEW COMMENTS` are added by you, you are free to change these parts.
|
||||
- Anything before them is from me, you are not allowed to change it, except to fix typos or grammar mistakes or explicitly instructed by me later.
|
||||
|
||||
## Identify the Task File
|
||||
|
||||
@@ -77,7 +80,7 @@ I will put my reply here
|
||||
- You should de-ambiguous proactively, if there is an obvious best answer to the review comment, you should also propose your solution:
|
||||
- You can find my preference in `REPO-ROOT/.github/Guidelines/Coding.md`.
|
||||
- Review comments should only be created when you can't find any reasonable solution to the issue, or can't make any reasonable decision because of the ambiguity.
|
||||
- If anything in the the task is incorrect, just make change directly instead of putting a review comment.
|
||||
- If anything in the the task is incorrect, only make changes for typos and grammar mistakes, fact mistakes should be put in `## DETAILS`, or when it causes unresolvable ambiguity, put it in `## REVIEW COMMENTS`.
|
||||
- If there are ambiguity or missing details, but you are able to figure it out, just add them to `## DETAILS` or `## VERIFICATION` section of the task file, instead of putting a review comment.
|
||||
- Take into accounts of my replies to all review comments.
|
||||
- Expand missing details:
|
||||
|
||||
Reference in New Issue
Block a user