Skip to content

Commit

Permalink
Properly unsubscribe any module from a topic when it gets deregistere…
Browse files Browse the repository at this point in the history
…d. Updated readme with small libmodule example.
  • Loading branch information
FedeDP committed Jul 2, 2019
1 parent f0cea12 commit 50d20d3
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 7 deletions.
13 changes: 13 additions & 0 deletions Lib/pubsub.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ static void destroy_pubsub_msg(pubsub_priv_t *pubsub_msg);
static module_ret_code tell_pubsub_msg(pubsub_priv_t *m, module *mod, m_context *c);
static module_ret_code publish_msg(const module *mod, const char *topic, const unsigned char *message,
const ssize_t size, const bool autofree);
static map_ret_code unsubscribe(void *data, const char *key, void *value);

static map_ret_code tell_if(void *data, const char *key, void *value) {
module *mod = (module *)value;
Expand Down Expand Up @@ -90,6 +91,16 @@ static module_ret_code publish_msg(const module *mod, const char *topic, const u
return MOD_ERR;
}

static map_ret_code unsubscribe(void *data, const char *key, void *value) {
module *mod = (module *)value;
const char *topic = (const char *)data;

if (map_has_key(mod->subscriptions, topic)) {
map_remove(mod->subscriptions, topic);
}
return MAP_OK;
}

/** Private API **/

module_ret_code tell_system_pubsub_msg(m_context *c, enum msg_type type, const self_t *sender, const char *topic) {
Expand Down Expand Up @@ -169,6 +180,8 @@ module_ret_code module_deregister_topic(const self_t *self, const char *topic) {
/* Only same mod which registered topic can deregister it */
if (tmp == mod) {
if (map_remove(c->topics, topic) == MAP_OK) {
/* Automatically unsubscribe any module subscribed to topic */
map_iterate(c->modules, unsubscribe, (void *)topic);
tell_system_pubsub_msg(c, TOPIC_DEREGISTERED, self, topic);
return MOD_OK;
}
Expand Down
57 changes: 57 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,63 @@ Indeed, libmodule was heavily inspired by my own actor library experience with [

Unsurprisingly, module is the core concept of libmodule architecture.
A module is an Actor that can listen on socket events too.
Frankly speaking, it is denoted by a MODULE() macro plus a bunch of callbacks, eg:
```
cat pippo.c
#include <module/module_easy.h>
#include <module/modules_easy.h>
#include <string.h>
#include <ctype.h>
MODULE("Foo");
static void init(void) {
m_register_fd(STDIN_FILENO, 0, NULL);
}
static bool check(void) {
return true;
}
static bool evaluate(void) {
return true;
}
static void destroy(void) {
}
static void receive(const msg_t *msg, const void *userdata) {
if (!msg->is_pubsub) {
char c;
read(msg->fd_msg->fd, &c, sizeof(char));
switch (tolower(c)) {
case 'q':
m_log("Leaving...\n");
m_tell(self(), "ByeBye");
break;
default:
m_log("Pressed %c\n", c);
break;
}
} else if (msg->pubsub_msg->type == USER &&
!strcmp((char *)msg->pubsub_msg->message, "ByeBye")) {
modules_quit(0);
}
}
```
```
cat main.c
#include <module/modules_easy.h>
int main() {
return modules_loop();
}
```
In this example, a "Foo" module is created and will read chars from stdin until 'q' is pressed.

## Is it portable?

Expand Down
14 changes: 7 additions & 7 deletions Samples/Easy/pippo.c
Original file line number Diff line number Diff line change
Expand Up @@ -118,13 +118,13 @@ static void receive(const msg_t *msg, const void *userdata) {
}
break;
}
} else {
if (msg->pubsub_msg->type == USER && !strcmp((char *)msg->pubsub_msg->message, "BauBau")) {
m_become(ready);
/* Finally register Leaving topic */
m_register_topic("leaving");
m_log("Press 'p' to play with Doggo! Or 'f' to feed your Doggo. 's' to have a nap. 'w' to wake him up. 'q' to leave him for now.\n");
}
} else if (msg->pubsub_msg->type == USER &&
!strcmp((char *)msg->pubsub_msg->message, "BauBau")) {

m_become(ready);
/* Finally register Leaving topic */
m_register_topic("leaving");
m_log("Press 'p' to play with Doggo! Or 'f' to feed your Doggo. 's' to have a nap. 'w' to wake him up. 'q' to leave him for now.\n");
}
}

Expand Down
3 changes: 3 additions & 0 deletions TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
- [x] Avoid telling system messages like MODULE_STARTED/TOPIC_REGISTERED to ourselves
- [x] Test pubsub messagging for paused modules
- [x] Fix memleaks!
- [x] Unsubscribe every module when a topic gets deregistered

### Generic
- [x] Add some diagnostic API, eg: module_dump() (to dump each module's state)
Expand All @@ -30,6 +31,7 @@
- [x] module_tell/publish/broadcast
- [x] MODULE_STARTED/MODULE_STOPPED new sysmessages
- [x] Avoid telling system messages like MODULE_STARTED/TOPIC_REGISTERED to ourselves
- [ ] Add doc for new deregister_topic behaviour (ie: it automatically unsubscribes any module subscribed)
- [ ] Add a new page about trusting pointers

### Samples
Expand All @@ -38,6 +40,7 @@
### Test
- [x] Fix tests
- [x] add module_dump tests
- [ ] Add test to new deregister_topic behaviour (ie: it automatically unsubscribes any module subscribed)

## 5.1.0

Expand Down

0 comments on commit 50d20d3

Please sign in to comment.