This file is indexed.

/usr/lib/ocaml/netplex/netplex_internal.mli is in libocamlnet-ocaml-dev 4.1.2-3.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
(* $Id$ *)

(** Internal services *)

(** Internal services are available to multi-threaded programs only, and
    implemented via {!Netsys_polysocket}.

    See below for an introduction.
 *)

val register_server : string -> Netplex_types.polyserver_box -> unit
  (** [register_server name server]: registers a server under the given
      [name]. It is an error if a server is already registered for the
      same name.

      The registration is thread-safe.
   *)

val connect_client :
      'a Netplex_types.kind_check ->
      int -> string ->
        'a Netsys_polysocket.polyclient
  (** [connect_client is_kind n name]: Creates a new polyclient that is
      connected to the registered service [name]. The arg [is_kind] determines 
      the type of the messages that can be exchanged. The number [n] is the
      size of the pipe buffer, in number of messages.

      The function fails if the service is not registered, or assumes the wrong
      message kind.

      The client lookup is thread-safe.

      Example how to invoke a service exchanging strings (kind [Tstring]):
      {[
let same : type s t . s polysocket_kind * t polysocket_kind -> (s,t) eq =
  function
  | Tstring, Tstring -> Equal
  | _ -> Not_equal

let client =
  Netplex_internal.connect_client
    { Netplex_types.kind_check = fun k -> same(Tstring,k) }
    n
    "name"
      ]}

      (You should strictly stick to this pattern. Any abbreviation will probably
      not type-check.)
   *)


(** {2:intro How to configure and use internal services}

Internal services are a fast mechanism to invoke containers from other
containers. So far, internal services are only available for multi-threaded
programs. The messages can have any type.

You add an internal service by configuring an address "internal" in the
protocol section of the configuration file, e.g.

{[
protocol {
  name = "my-protocol";
  address {
    type = "internal";
    name = "my-identifier";
  }
  address {                    (* other addresses ok *)
    ...
  }
}
]}

The internal service is only activated when multi-threading is selected.
In programs using multi-processing the internal service is simply ignored.

You need to choose the types of your messages. There is the GADT
{!Netplex_types.polysocket_kind} listing possible types. It comes with
the variants [Txdr] (for RPC messaging) and [Tstring] (for any custom strings):

{[
type _ polysocket_kind = ..
type _ polysocket_kind +=
   | Txdr : Netxdr.xdr_value polysocket_kind
   | Tstring : string polysocket_kind
]}

This is an extensible GADT, i.e. you can add more variants with the "+="
notation. (Note that extensible variants are first available since
OCaml-4.02. With older OCaml versions, you cannot extend more variants.)

Let's add integers:

{[
type _ polysocket_kind +=
  | Tint : int polysocket_kind
]}

The connections to the internal services do not arrive via the normal
[process] mechanism. There is a second path using the new processor
hooks [config_internal] and [process_internal]. The hook [config_internal]
defines which message type you are really using. The hook [process_internal]
is invoked when a new connection to the internal service is established.
It works very much like [process], only that it doesn't use file descriptors
but so-called polysockets (see {!Netsys_polysocket}).

{[
class hello_world_processor hooks : processor =
object(self)
  inherit Netplex_kit.processor_base hooks

  method config_internal =
     [ "my-protocol", Polysocket_kind_box Tint ]

  method process_internal ~when_done container srvbox proto_name =
    let Polyserver_box(kind, srv) = srvbox in
    match kind with
      | Tint ->
         let endpoint = Netsys_polysocket.accept ~nonblock:false srv in
         (* Now send and receive messages over endpoint *)
         ...;
         when_done()
      | _ ->
         failwith "wrong kind"

  method process ~when_done container fd proto_name =
    (* this is still invoked when non-internal connections arrive *)
    ...
  method supported_ptypes = 
    ...
end
]}

The [endpoint] is actually a pair of polypipes ({!Netsys_polypipe}):

{[
let (rd, wr) = endpoint
]}

Over [rd] you receive messages of type [int] from the client, and via
[wr] you can send messages to it.

Use {!Netplex_internal.connect_client} to get a client (usually in a
different container, or in an arbitrary other thread):

{[
let same : type s t . s polysocket_kind * t polysocket_kind -> (s,t) eq =
  function
  | Tint, Tint -> Equal
  | _ -> Not_equal

let client =
  Netplex_internal.connect_client
    { Netplex_types.kind_check = fun k -> same(Tint,k) }
    5
    "my-identifier" in
let client_endpoint =
   Netsys_polysocket.endpoint ~synchronous:true ~nonblock:false client
]}

Again, the endpoint is a pair of polypipes in reality:

{[
let (client_rd, client_wr) = client_endpoint
]}

{3 Complete example}

You find a complete example in the distribution tarball at
[code/examples/netplex/internal_service.ml].



{2 Using internal services via RPC}

RPC clients and servers have now support for polysockets. Note that
you need to select [Txdr] as message kind. The messages are not serialized
into strings, but instead the structured XDR format is used as transport
encoding.

XXX TODO

 *)