Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Supports broadcast events to all Nginx workers #38

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
xfeep opened this issue Aug 15, 2014 · 1 comment
Closed

Supports broadcast events to all Nginx workers #38

xfeep opened this issue Aug 15, 2014 · 1 comment
Labels
Milestone

Comments

@xfeep
Copy link
Member

xfeep commented Aug 15, 2014

Suppose our Nginx instance has 4 workers (worker process not jvm_workers which is just thread number of thread pool in jvm). Now we want to provide sub/pub service. e.g.

  1. Client A connected to nginx worker A and subscribed to uri /mychannel/sub
  2. Client B connected to nginx worker B and subscribed to uri /mychannel/sub
  3. Client C connected to nginx worker C and publish a message to uri /mychannel/pub

So the service at endpoint of /mychannel/pub must broadcast pub event to Client A and Client B.
Although for large-scale application we can use sub/pub service from Redis on nginx-clojure , for small-scale or medium-scale application this feature will make the dev life easier.

This feature will support two kinds of events to broadcast, simple events and complex events.

  1. A simple event only has a event id which is a long integer and must be less than 0x0100000000000000L, it hasn't any body or its body is stored in some external stores, e.g. SharedHashMap, Memcached, Redis etc.
  2. A complex event has a message with a length limitation PIPE_BUF - 8, generally on Linux/Windows is 4088, on MacosX is 504.
@xfeep xfeep added this to the 0.2.5 milestone Aug 15, 2014
@xfeep xfeep added the feature label Aug 15, 2014
xfeep added a commit that referenced this issue Aug 15, 2014
@xfeep
Copy link
Member Author

xfeep commented Aug 27, 2014

broadcast API.

For clojure

(defn broadcast!
  "Broadcast a  event to all nginx worker processes. 
   This function can be used to notify all subscribers in different nginx
worker processes from the same nginx instance.
   `event has the form {:data data} or {:tag tag, :data data} 
   `data can be Long, String, byte[]. If it is long integer it must be less than 0x0100000000000000L
If it is string or bytes, it must be less than PIPE_BUF - 8, generally on Linux/Windows is 4088, 
on MacosX is 504
     `data will be truncated if its length exceeds this limitation.
   If `tag is given, `data can also be long integer which means this event is 
   very simple and only has a event id without any body or body is stored externally.
   The default tag value is 0x20 when `msg is Long otherwise the default value is 0x80.
   Here is a list of `tag values range:
   * System Event :0x00 ~ 0x1f -- Application should not use them
     * Application Event : 0x20 ~ 0xff
     * Simple  Event : 0x00 ~ 0x7f, only event id (7Byte), no message body
     * Complex Event : 0x80 ~ 0xff"
  [event])

(defn on-broadcast! 
  "Add a broadcasted event listener.
   Function f is like (fn[event] ... ) and event has the form {:tag tag, :data `bytes or long`, :offset offset :length length }
   `offset & `length are meamingless if data is a long integer."
  [f]);

(defn on-broadcast-event-decode!
  "Add a pair of tester & decoder to broadcast event decoder chain.
   Decoders will be called one by one and the current decode result will be past to the next decoder.
   Decoders should return decoded event which has the form {:tag tag, :data `any type of data`, :offset offset :length length }
   offset & `length are meamingless if data is a long integer.
   Function tester is a checker and only if it return true the decoder will be invoked."
  [tester decoder]);

For Java/Groovy

public class NginxClojureRT extends MiniConstants {
          public static AppEventListenerManager getAppEventListenerManager() ;
}
public class AppEventListenerManager {
    public void broadcast(PostedEvent e);
    public void addDecoder(Decoder d) ;
    public boolean removeDecoder(Decoder d) ;
    public void addListener(Listener listener) ;
    public boolean removeListener(Listener listener) ;

    public static interface Decoder {
        public boolean shouldDecode(PostedEvent event);
        public PostedEvent decode(PostedEvent event);
    }

    public static interface Listener {
        /**
         * Because event.data will be reused by next event so this listener must handle it carefully and
         * do use it out of this invoking scope.
         * */
        public void onEvent(PostedEvent event);
    }

    public static class PostedEvent {
        public int tag;
        public Object data;
        public int offset;
        public int length;
        /*....some constructors of PostedEvent*/
}

This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant