discourse/config
David Taylor 31db83527b DEV: Introduce PresenceChannel API for core and plugin use
PresenceChannel aims to be a generic system for allow the server, and end-users, to track the number and identity of users performing a specific task on the site. For example, it might be used to track who is currently 'replying' to a specific topic, editing a specific wiki post, etc.

A few key pieces of information about the system:
- PresenceChannels are identified by a name of the format `/prefix/blah`, where `prefix` has been configured by some core/plugin implementation, and `blah` can be any string the implementation wants to use.
- Presence is a boolean thing - each user is either present, or not present. If a user has multiple clients 'present' in a channel, they will be deduplicated so that the user is only counted once
- Developers can configure the existence and configuration of channels 'just in time' using a callback. The result of this is cached for 2 minutes.
- Configuration of a channel can specify permissions in a similar way to MessageBus (public boolean, a list of allowed_user_ids, and a list of allowed_group_ids). A channel can also be placed in 'count_only' mode, where the identity of present users is not revealed to end-users.
- The backend implementation uses redis lua scripts, and is designed to scale well. In the future, hard limits may be introduced on the maximum number of users that can be present in a channel.
- Clients can enter/leave at will. If a client has not marked itself 'present' in the last 60 seconds, they will automatically 'leave' the channel. The JS implementation takes care of this regular check-in.
- On the client-side, PresenceChannel instances can be fetched from the `presence` ember service. Each PresenceChannel can be used entered/left/subscribed/unsubscribed, and the service will automatically deduplicate information before interacting with the server.
- When a client joins a PresenceChannel, the JS implementation will automatically make a GET request for the current channel state. To avoid this, the channel state can be serialized into one of your existing endpoints, and then passed to the `subscribe` method on the channel.
- The PresenceChannel JS object is an ember object. The `users` and `count` property can be used directly in ember templates, and in computed properties.
- It is important to make sure that you `unsubscribe()` and `leave()` any PresenceChannel objects after use

An example implementation may look something like this. On the server:

```ruby
register_presence_channel_prefix("site") do |channel|
  next nil unless channel == "/site/online"
  PresenceChannel::Config.new(public: true)
end
```

And on the client, a component could be implemented like this:

```javascript
import Component from "@ember/component";
import { inject as service } from "@ember/service";

export default Component.extend({
  presence: service(),
  init() {
    this._super(...arguments);
    this.set("presenceChannel", this.presence.getChannel("/site/online"));
  },
  didInsertElement() {
    this.presenceChannel.enter();
    this.presenceChannel.subscribe();
  },
  willDestroyElement() {
    this.presenceChannel.leave();
    this.presenceChannel.unsubscribe();
  },
});
```

With this template:

```handlebars
Online: {{presenceChannel.count}}
<ul>
  {{#each presenceChannel.users as |user|}} 
    <li>{{avatar user imageSize="tiny"}} {{user.username}}</li>
  {{/each}}
</ul>
```
2021-08-27 16:26:06 +01:00
..
cloud/cloud66 DEV: enable frozen string literal on all files 2019-05-13 09:31:32 +08:00
environments DEV: Skip CSS watcher when running QUnit tests and expose more Chrome logs (#13390) 2021-06-15 18:27:15 +03:00
initializers DEV: Compile core and plugin stylesheets independently of themes (#13638) 2021-07-06 13:11:10 -04:00
locales UX: Add Styling step to wizard (#14132) 2021-08-25 17:10:12 -04:00
application.rb DEV: Allow us to use Ember CLI assets in production 2021-08-05 08:32:33 -04:00
boot.rb DEV: Remove deprecated bootsnap options (#11929) 2021-02-02 14:39:51 +01:00
cdn.yml.sample Initial release of Discourse 2013-02-05 14:16:51 -05:00
database.yml DEV: Correct typos and spelling mistakes (#12812) 2021-05-21 11:43:47 +10:00
deploy.rb.sample enough with the malloc limit, not needed 2016-05-25 21:09:07 +10:00
dev_defaults.yml FEATURE: Add post edits count to user activity (#13495) 2021-08-02 10:15:53 -04:00
discourse_defaults.conf FEATURE: Add global admin api key rate limiter (#12527) 2021-06-03 10:52:43 +01:00
discourse.config.sample enough with the malloc limit, not needed 2016-05-25 21:09:07 +10:00
discourse.pill.sample Improve bluepill sample config. 2014-01-31 16:09:35 -05:00
environment.rb DEV: enable frozen string literal on all files 2019-05-13 09:31:32 +08:00
logrotate.conf Replace Clockwork with Sidetiq 2013-08-14 21:39:40 +02:00
multisite.yml.production-sample DEV: Remove db_id from sample multisite config. 2020-05-29 10:48:29 +08:00
nginx.global.conf Address @Supermathie's concerns in PR1430 2013-09-30 16:28:22 -04:00
nginx.sample.conf FEATURE: Optimize images before upload (#13432) 2021-06-23 12:31:12 -03:00
projections.json DEV: Use .hbr for raw template file extension (#8883) 2020-02-11 13:38:12 -06:00
puma.rb remove daemonize setting (#12232) 2021-03-01 16:42:50 +11:00
routes.rb DEV: Introduce PresenceChannel API for core and plugin use 2021-08-27 16:26:06 +01:00
sidekiq.yml FEATURE: introduce ultra_low priority queue 2019-01-17 14:53:19 +11:00
site_settings.yml DEV: Do not abort direct S3 uploads if upload_debug_mode enabled (#14141) 2021-08-25 14:48:06 +10:00
spring.rb DEV: enable frozen string literal on all files 2019-05-13 09:31:32 +08:00
thin.yml.sample Add sample Capistrano deployment files 2013-05-02 19:53:37 -07:00
unicorn_launcher FIX: Increase timeout when trying to reload unicorn. 2018-12-04 13:43:14 +08:00
unicorn_upstart.conf enough with the malloc limit, not needed 2016-05-25 21:09:07 +10:00
unicorn.conf.rb Revert "DEV: suppress assets logs from qunit tests (#13871)" 2021-07-29 13:28:24 +08:00