laravel-echo-server icon indicating copy to clipboard operation
laravel-echo-server copied to clipboard

[ WIP ] Simple plugin system

Open IfnotFr opened this issue 6 years ago • 15 comments

Hi,

This is a work in progress but functional plugin system allowing us to inject plugins (The WIP is for allowing us to discuss about this implementation before merging)

The code

I created a simple plugin handler Plugins with a singleton system based on a static emit method. It allows us to :

  • Instanciate the handler in the EchoServer with a clean object logic
  • Call the Plugins.emit(/* ... */) where we want in the package for simple hook calls

How to use it

Create a plugin where you want (example /absolute/path/to/my_plugin.js) :

module.exports = {
  install: function (events) {
    events.on('started-server', this.onServerStarted);
    events.on('broadcasting-event', this.onBroadcastingEvent);
  },

  onServerStarted: function () {
    // Do something when the server is started
  },

  onBroadcastingEvent: function (options) {
    // Do something when we broadcast an event.
    // Available params : `options.channel` and `options.message`
  }
};

Reference this plugin into your laravel-echo-server.json file :

{
  "plugins": [
    "/absolute/path/to/my/plugin.js"
  ]
}

Why ? And some use cases

Initially I wanted to add an external logger and a statistics system to this package. After some digging I found that I should rewrite a bunch of code for this. I think a simple plugin system will allow us to add flexibility for our usages (as main users are developers and we are using this package for our infrastructure).

Use cases :

  • Simple external logger for finding problems etc ...
  • A statistics system like Pusher for monitor the production load
  • ...

Conventions

  • Event name should be a verb.
  • Event name should in lower camel case
  • Event name should be ending with -ing if it is before an action
  • Event name should be ending with -ed if it is after an action

Next

We should :

  • [x] Be ok with the naming conventions :)
  • [x] Add more hooks into the code for building a clean and usefull plugin api
  • [ ] Write a complete reference of all hooks available in the package
  • [ ] Merge this ? :)

IfnotFr avatar Mar 29 '18 17:03 IfnotFr

A simple logger plugin would be cool to have built in so people don't have to re-write it every time... (optional, of course)

Maybe also be able to provide the plugin with some arguments?

AndrewMast avatar Mar 29 '18 17:03 AndrewMast

For the built-in logger system de need some work that i cannot do :

  • Rename the actual log system (used in devMode)
  • Rework the devMode for allowing to : do not log, log in console, log in files.
  • Add some log level options in options

What do you mean with options ?

IfnotFr avatar Mar 29 '18 17:03 IfnotFr

By me wondering if arguments could be provided to the plugins, I was thinking of a situation kinda like this:

  1. You had two different configs (one for development on your machine and one for the server)
  2. You wanted to use your same custom logger, but you wanted it to a slightly different thing for each server. (Maybe log to the console on your machine and log to a file on the server)

Maybe plugins could be referenced in both of these ways?

{
  "plugins": [
    "/absolute/path/to/my/plugin.js",
    {
      "path": "/absolute/path/to/my/plugin.js",
      "arguments": {"log_driver": "file"}
    }
  ]
}

AndrewMast avatar Mar 29 '18 18:03 AndrewMast

I make the syntax a little bit confusing. What about giving the complete config file (laravel-echo-server.json) to the module ?

I think it is more flexible without adding an alternative syntax.

If you dont want to rewrite the log into your package and you want to provide a log module, what about a module folder into your app with "official" modules ? (Then when you want you can merge some really useful modules into the core)

And i mean, the "official" modules can be loaded with relative path of the folder.

IfnotFr avatar Mar 29 '18 22:03 IfnotFr

I added a plugins folder outside of the project with an example.js plugin. And I added the ability to load official plugins from it without an absolute path (bd02e31, f790679)

"plugins": [
  "example.js"
]

Also I added more events, but i am not really familiar with the internal logic so any review / completion of the events i wrote will be appreciated :) (941c967, 35ba590)

And at least i added the ability to bring server options into plugins (3f3cb34)

IfnotFr avatar Mar 30 '18 14:03 IfnotFr

I was wondering if install was a good function name for the plugin. Would register make more sense?

AndrewMast avatar Mar 30 '18 15:03 AndrewMast

I agree, i prefer register too. I wonder why Vuejs plugins are register this way (with a install method). And as i am working with Vuejs since a year i did it automatically ;)

IfnotFr avatar Mar 30 '18 15:03 IfnotFr

Ok some heads up. I am testing this on production with custom plugins it works well and is really usefull. Hooking on broadcasting-message allows me to count messages and send some statistics on a custom panel etc ...

So, in order to moving forward. Please are we ok with the naming conventions I brought ?

IfnotFr avatar Apr 03 '18 12:04 IfnotFr

any updates?

zek avatar Nov 01 '18 14:11 zek

For merging this, i need the checklist to be done.

@AndrewMast Are we okay with the naming convention ? Furthermore, are my hooks looking good ? I need validation and conflict fix :)

At last i will wrote the documentation into the README.

IfnotFr avatar Nov 02 '18 09:11 IfnotFr

@Ifnot Yes, the naming convention and hooks looks good :D

AndrewMast avatar Nov 02 '18 13:11 AndrewMast

Okay :)

Where do you want to write the doc of the plugin ? Directly on the README or into a wiki page ?

Can you resolve the conflict for preparing the merge ?

Thanks.

IfnotFr avatar Nov 08 '18 09:11 IfnotFr

You should write the doc of the plugin on the README as this repo does not have any wiki pages. I currently do not have time to resolve the conflict, sorry.

AndrewMast avatar Nov 08 '18 14:11 AndrewMast

What's the current state of this plugin system? Nearly two years without an update :)

renepardon avatar Oct 28 '21 13:10 renepardon

I scaffolded a working system and used it internally on my projects two years ago.

But I didn't had the time finishing the glue and doc around it for merging into this project.

Any help for review the conflicts are welcome on this thread :)

IfnotFr avatar Oct 28 '21 14:10 IfnotFr