Coder Social home page Coder Social logo

remotiatr's People

Stargazers

 avatar  avatar  avatar

Watchers

 avatar

Forkers

funclun bubdm

remotiatr's Issues

Create A TCP Message Transport

Implement a raw TCP message transport. While HTTP runs over TCP, it would be more efficient to have a lower level implementation since we don't make use of HTTP specific features. Also, this implementation will support applications that don't use the MVC IApplicationBuilder, so that it can run on just about any server.

  • Create a new set of projects for the extension from the Extension Template in src/MessageTransport named "Tcp"
  • Implement a client-side IMessageTransport that uses a TcpClient to send the message. The transport just needs to send the message Stream to the uri, and receive the response. You can use DefaultHttpMessageTransport from RemotiatR.MessageTransport.Http.Client as an example, but skip implementing batching and other advanced concepts for now.
  • Implement a server-side configuration to get a TRemotiatr from the service collection and hook it up to a TcpListener. It should be somewhat similar to the ProcessSingle method of IApplicationBuilderExtensions of RemotiatR.MessageTransport.Http.Server.
  • Similar configuration options should be available client and server side to those for the HTTP message transport.

Create A Binary IMessageSerializer

Follow the patterns of DefaultJsonMessageSerializer to create a binary serializer. The serializer should support self-referencing object graphs and preserve types (the same as the JSON serializer). This serializer should focus specifically on compressing the message size as much as possible without losing any precision.

Implement Message Caching

Message caching should be configurable on the client and on the server so that two matching requests can return a cached response.

I'm still working out the details on this. Primarily, I'm working through the details of what a "matching" request should be; should it require an exact match, some sort of matching func, or something else. Feel free to share your thoughts.

Enhance HTTP Message Transport Batching

Right now the HTTP message transport works and supports batching, but the batching support can be enhanced in the following ways:

  • Add support for message streaming. Replace the use of the message-lengths header with the Transfer-Encoding: chunked header, and write the chunk sizes to the stream before each message. See this link for brief details. Once this is complete the messages should stream and become available as soon as they are written. You might test this by adding a delay between writing each message and seeing if they arrive one after another, or if it waits until the end to send the whole request.
  • Allow for partial success; in the case that some of the messages are processed successfully their responses should be returned even if some of the messages throw an exception (on the client or the server). To support this, before each message stream is written to the HTTP stream, a header indicating success or failure should be written. Then on the receiving end it should read the header first and then branch the logic based on the outcome.
  • Allow messages to be written out of order. When the initial request written add a message id prefix to each message similar to the chunked length prefix. Then, as soon as handlers complete for messages write them to the response stream with their id, and pair them back up to their original request on the client. The goal is that the fastest running requests should complete and send back to the client as soon as they are done rather than waiting for the longest running request to finish.
  • Add support for configuring the batching timeout. Right now it is set to a constant time, but you should be able to configure it similar to other configuration patterns in this code base.
  • Add support for additional batching configurations. You should be able to set the following configurations:
    • Minimum timeout; this is the one that already exists as a constant value
    • Debounce timeout; this is the minimum timeout applied to each message added to a batch. If the time left for the "minimum timeout" is greater than this, then this value should be ignored. It should do this for each additional message.
    • Maximum timeout; this is the maximum amount of time from the initial message that is allowed before a batch is sent. This value is used if the debounce timeout applied from receiving a message would push the total timeout over this limit.
    • Maximum message count; if the number of messages in the batch reaches this number then the batch will be sent immediately.

Feel free to create a PR per main bullet.

Add Second Server To Example Project

This ticket is to add a second server to the example project to prove and demonstrate the multi-server capabilities of the library.

  • Copy the server project src/Example/Server to src/Example and rename it ReportServer. Fix project and path names and add the project to the ContosoUniversity.sln and RemotiatR solutions.
  • Delete the About and Dashboard features from the Server project
  • Delete everything but the About and Dashboard features from the ReportServer projects and any supporting infrastructure
  • Do all the above steps for the Shared project as well. Then fix all the project references to point to the correct project (ReportServer references ReportShared, Client references both Shared and ReportShared, etc)
  • Assign a new URI to the ReportServer project
  • Add a new project that is just responsible for starting up the server and report server processes. Move the pre-build script from the server project to this new project, and make sure to remove it from the report server project as well
  • Add a host to the client project Startup, and configure it to use the new report server
  • Test and ensure that you can still view the pages that receive data from either server

Implement A NoopSerializer

This ticket is to create a default NoopSerializer that will be used when no other serializer is specified. This serializer will primarily be used when the registered message transport ignores the serialization result anyways.

  • Create a new set of projects for the extension from the Extension Template in src/Serializer named "Noop"
  • Use Serializer\Json as a template to implement a the new serializer and registration code.
  • The serializer should return a Stream that throws an exception if you actually attempt to read from it. The exception should inform you that you must either replace the no-op serializer with an actual serializer or you must use a message transport that does not use a serializer.

Add RESTful HTTP Message Transport

A basic HTTP message transport exists that will be used for organizations that don't need to take advantage of HTTP extensions such as server logging, API documentation, and middle tier request caching. This ticket is to create a new HTTP message transport that will produce more standard RESTful HTTP requests.

  • Create a new set of projects for the extension from the Extension Template in src/MessageTransport named "RestfulHttp"
  • Add client side configuration; see other projects in this code base for how configuration should be done.
    • Add configuration to determine which messages should be considered queries (GET), update (PUT), and create/action operations (POST) (See the bottom of this ticket for details on when each should be used). The configuration should allow the user to configure a Func<Type,HttpMethod>, where HttpMethod is an enum constrained to GET, PUT, POST, DELETE. Provide a reasonable default configuration, something like "all types with the postfix 'query' (non-case-sensitive) are GET, everything else is POST.
    • Add override of the default URI generator. The override should produce a URI path based on the namespace and type of the message, and should append an id value if the message request contains a property called "id" (case-insensitive).
  • Implement a message transport for the client; see the HTTP message transport project to get an idea of how.
    • Create an IMessageQueryStringSerializer interface that extends IMessageSerializer. Create a default query string serializer that serializes the message object to a query string format, using the format "Parent.Child.Grandchild" for nested properties.
    • When receiving a message it should first determine what HTTP method it will use to send
      • If PUT or POST, set the HTTP method and set the stream to the request body.
      • If GET, set the HTTP method and the id for the message type to the URI. Then, serialize the message using the IMessageQueryStringSerialzier. If the length is less than 2048 characters (make this value configurable), set it as the URL query string. If the length exceeds 2048, generate a SHA-256 hash of the message content and set it is "?~hash={hash}" (make this value configurable), then set the default message stream to the body of the request instead.
    • On the server implement a server handler that can handle the special case for queries beginning with ~hash, mapping from query string parameters, or mapping from the request body.

Additional details about GET, PUT, POST

  • GET - this is used for queries, and the affect on the server should be nullimpotent. That is, sending this message should not affect the state of the data on the server
  • PUT - this is for updates, and the affect on the server should be idempotent. That is, the first time you send this request it will change some state on the server, but sending the same request multiple times will not have an additional affect (ie: if I update the name of a user to 'Ted', and then update it again to 'Ted', the user's name will still not change between the first and second request)
  • POST - this should be used for creation and actions. Each time this message is sent it will likely have additional affects (ie: if I create a user, and then create a user, the second message will create a user in addition to the first)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.