{"action":"created","issue":{"url":"https://api.github.com/repos/processone/ejabberd/issues/1385","repository_url":"https://api.github.com/repos/processone/ejabberd","labels_url":"https://api.github.com/repos/processone/ejabberd/issues/1385/labels{/name}","comments_url":"https://api.github.com/repos/processone/ejabberd/issues/1385/comments","events_url":"https://api.github.com/repos/processone/ejabberd/issues/1385/events","html_url":"https://github.com/processone/ejabberd/issues/1385","id":190403642,"number":1385,"title":"Question: Does MUC/SUB require persistent rooms?","user":{"login":"genexp","id":816,"avatar_url":"https://avatars.githubusercontent.com/u/816?v=3","gravatar_id":"","url":"https://api.github.com/users/genexp","html_url":"https://github.com/genexp","followers_url":"https://api.github.com/users/genexp/followers","following_url":"https://api.github.com/users/genexp/following{/other_user}","gists_url":"https://api.github.com/users/genexp/gists{/gist_id}","starred_url":"https://api.github.com/users/genexp/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/genexp/subscriptions","organizations_url":"https://api.github.com/users/genexp/orgs","repos_url":"https://api.github.com/users/genexp/repos","events_url":"https://api.github.com/users/genexp/events{/privacy}","received_events_url":"https://api.github.com/users/genexp/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":1,"created_at":"2016-11-18T19:38:00Z","updated_at":"2016-11-21T12:50:18Z","closed_at":null,"body":"> What version of ejabberd are you using?\r\n\r\nlatest\r\n\r\n> What operating system (version) are you using?\r\n\r\nUbuntu Xenial\r\n\r\n> How did you install ejabberd (source, package, distribution)?\r\n\r\nProcessOne distribution\r\n\r\nWe use SQL to store history, and other bits of information generated by eJabberd.  We plan to use it to store subscriptions as well.  Our rooms are all set to temporary, but each rooms name is deterministic.  When everyone leaves a room, the room is destroyed, however, when the same user reconnects the room is recreated with the same name.\r\n\r\nWe'd like to understand more how subscriptions work with temporary rooms.  IF we save subscriptions in SQL, leave the room to temporary, the data will persist even after the room process is stopped.  When a user joins a new room with the exact same JID, will the new room use the same subscriptions?  Is there a way to reload them from SQL if not?\r\n\r\nWe'd like to avoid the need for permanent rooms, as we create hundreds of thousands of them and they cause a significant performance issue (32gb nodes were dying daily), while leaving them set to temporary keeps ejabberd at a cool 5% of memory :)\r\n"},"comment":{"url":"https://api.github.com/repos/processone/ejabberd/issues/comments/261928440","html_url":"https://github.com/processone/ejabberd/issues/1385#issuecomment-261928440","issue_url":"https://api.github.com/repos/processone/ejabberd/issues/1385","id":261928440,"user":{"login":"badlop","id":96807,"avatar_url":"https://avatars.githubusercontent.com/u/96807?v=3","gravatar_id":"","url":"https://api.github.com/users/badlop","html_url":"https://github.com/badlop","followers_url":"https://api.github.com/users/badlop/followers","following_url":"https://api.github.com/users/badlop/following{/other_user}","gists_url":"https://api.github.com/users/badlop/gists{/gist_id}","starred_url":"https://api.github.com/users/badlop/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/badlop/subscriptions","organizations_url":"https://api.github.com/users/badlop/orgs","repos_url":"https://api.github.com/users/badlop/repos","events_url":"https://api.github.com/users/badlop/events{/privacy}","received_events_url":"https://api.github.com/users/badlop/received_events","type":"User","site_admin":false},"created_at":"2016-11-21T12:50:18Z","updated_at":"2016-11-21T12:50:18Z","body":"The list of subscribers is kept in the room process state for all rooms. For persistent rooms, which are stored in the muc_room Mnesia or SQL tables, the field 'subscribers' is filled accordingly. So, the subscriptions are not kept in an independent table, it's just another record in an existing table, and you can't separate recovering subscriptions from persistence, because they aren't independent steps when creating a room.\r\n\r\nA solution is that you take care to store subscriptions yourself for temporary rooms. The necessary changes in the source code I can think are:\r\n1. Create a custom table that stores for each roomjid the list of subscribedjids.\r\n2. In mod_muc_room:store_room/1 function, when room is temporary it does nothing. Add code so it stores the list of subscribers in your table\r\n3. In destroy_room/2, when room is temporary it does not remove it from database. Add code so it removes the entry from your table.\r\n4. In init function for temporary rooms, get your list of subscribers and use it too feed the new room. Example code for this:\r\n```\r\ndiff --git a/src/mod_muc_room.erl b/src/mod_muc_room.erl\r\nindex 5b00054..821a5e6 100644\r\n--- a/src/mod_muc_room.erl\r\n+++ b/src/mod_muc_room.erl\r\n@@ -108,6 +108,24 @@ start_link(Host, ServerHost, Access, Room, HistorySize, RoomShaper, Opts) ->\r\n %%% Callback functions from gen_fsm\r\n %%%----------------------------------------------------------------------\r\n \r\n+get_subscribers_stored(Room) ->\r\n+    Names = get_subscribers_sql(Room),\r\n+    List = [make_sub(Name) || Name <- Names],\r\n+    {subscribers, List}.\r\n+\r\n+%% TODO: Get this from database\r\n+get_subscribers_sql(Room) ->\r\n+    [<<\"user2\">>, <<\"user3\">>].\r\n+\r\n+make_sub(Name) ->\r\n+    {jid:make(Name,<<\"localhost\">>,<<\"\">>),\r\n+     <<\"mynick\">>,\r\n+     [<<\"urn:xmpp:mucsub:nodes:messages\">>,\r\n+      <<\"urn:xmpp:mucsub:nodes:affiliations\">>,\r\n+      <<\"urn:xmpp:mucsub:nodes:subject\">>,\r\n+      <<\"urn:xmpp:mucsub:nodes:config\">>]\r\n+    }.\r\n+\r\n init([Host, ServerHost, Access, Room, HistorySize,\r\n       RoomShaper, Creator, _Nick, DefRoomOpts]) ->\r\n     process_flag(trap_exit, true),\r\n@@ -119,7 +137,7 @@ init([Host, ServerHost, Access, Room, HistorySize,\r\n \t\t   jid = jid:make(Room, Host, <<\"\">>),\r\n \t\t   just_created = true,\r\n \t\t   room_shaper = Shaper}),\r\n-    State1 = set_opts(DefRoomOpts, State),\r\n+    State1 = set_opts([get_subscribers_stored(Room) | DefRoomOpts], State),\r\n     store_room(State1),\r\n     ?INFO_MSG(\"Created MUC room ~s@~s by ~s\",\r\n \t      [Room, Host, jid:to_string(Creator)]),\r\n```"}}
{"actor":{"display_login":"badlop"}}