I've developed a plugin for Wordpress that needs some extra tables in order to work properly. A few users have complained that when they try to "network-activate" it, it only works on the main blog.
So I found this discussion about how Wordpress should support these activations, but I don't understand how we plugin developers should handle the activation process
On 28 June 2011 12:42, Dino Termini <d...@duechiacchiere.it> wrote:
> Hi all,
> I've developed a plugin for Wordpress that needs some extra tables in order > to work properly. A few users have complained that when they try to > "network-activate" it, it only works on the main blog.
> So I found this discussion about how Wordpress should support these > activations, but I don't understand how we plugin developers should handle > the activation process
> Can someone please elaborate on it, maybe posting an example or a snippet of > code?
This [1] is the code I use in one of my plugins. Basically you detect if the activation is network-wide or not, and loop over each blog, installing the tables in turn.
*Beware* though, that this code is likely to timeout (ie. hit PHP's script execution time limit) if you have hundreds of blogs in your network, especially if you're adding tables to each blog. My plugin is only deployed in controlled environments so I know it'll be fine. If your plugin is going to be made publicly available you should look into a method similar to what scribu does in his Proper Network Activation plugin [2].
thank you for your feedback. I'm actually suggesting my users to install Scribu's plugin before they activate mine network-wide. Unfortunately some of them still report that it didn't help, and that only the tables for the main blog were created. I guess I'll have to look into adding some ajax to my plugin. My only concern is that this should be handled by Wordpress, not the plugin developers :)
> On 28 June 2011 12:42, Dino Termini<d...@duechiacchiere.it> wrote:
> *Beware* though, that this code is likely to timeout (ie. hit PHP's > script execution time limit) if you have hundreds of blogs in your > network, especially if you're adding tables to each blog. My plugin is > only deployed in controlled environments so I know it'll be fine. If > your plugin is going to be made publicly available you should look > into a method similar to what scribu does in his Proper Network > Activation plugin [2].
> thank you for your feedback. I'm actually suggesting my users to install Scribu's plugin before they activate mine network-wide. Unfortunately some of them still report that it didn't help, and that only the tables for the main blog were created. I guess I'll have to look into adding some ajax to my plugin. My only concern is that this should be handled by Wordpress, not the plugin developers :)
The correct solution is to not have a table per blog in a Multisite install.
Your plugin should either work with the existing table structure or introduce a global table because it needs to do something fundamentally different or not expect to work on any reasonably sized multisite install when network activated without manual work to create the tables.
Running through a table creation for every blog on a large multisite install is not scalable and is probably not what you need :)
For me, I noticed a strange thing about network activation.
I made a little test with 2 blogs and a network admin activation/deactivation (register_activation_hook / register_deactivation_hook). In the activation, I create a table for each blog, and in the deactivation, I remove the table.
My results are : - The activation is triggered for each blog. (Actually, only main blog at this time, but when I go into the dashboard of the second blog, it seems to be activate at this time because I see the table into my DB) - For the deactivation, only the main blog is triggered, even I go into the dashboard of the second blog.
So, why I didn't have the same behavior for Activation/Deactivation ?
Thanks.
Tommy
On Tue, 28 Jun 2011 08:56:31 -0400, Dino Termini
<d...@duechiacchiere.it> wrote: >> The correct solution is to not have a table per blog in a Multisite >> install.
> True, but what about uninstalling the plugin? How do I make sure no > other instances are still referencing the global table?
> WordPress never needs to create new tables for *all* blogs in a network in > one go. The new tables are created for one blog when that blog is created.
On Jun 28, 2011, at 8:48 AM, Peter Westwood wrote:
> The correct solution is to not have a table per blog in a Multisite install.
> Your plugin should either work with the existing table structure or introduce a global table because it needs to do something fundamentally different or not expect to work on any reasonably sized multisite install when network activated without manual work to create the tables.
> Running through a table creation for every blog on a large multisite install is not scalable and is probably not what you need :)
I've been thinking about this a lot lately as we're exploring building a SaaS using WordPress as a base.
I definitely agree that the current process does not scale to have to add tables when a plugin needs tables to all sites. So you proposed one option to create a shared table that has blog_id as a field so only one table needs to be added. But doesn't that effectively create a hybrid architecture where parts of the data are sharded and parts are not?
My understanding is that WordPress uses a sharding approach to enable scalability, yet it is recommending to not use sharding for extensions; isn't that contradictory? If sharding is the appropriate architecture for WordPress' tables why is it not the appropriate architecture for plugin's tables?
Or is this simple a case of "Yes, it's not a great situation but it's all we got at the moment?" And if that is the case, maybe it would make sense to come up with a better solution (i.e. a way that it is possible to add new tables to other blogs without timeout?)
<mikeschin...@newclarity.net> wrote: > I've been thinking about this a lot lately as we're exploring building a SaaS using WordPress as a base.
> I definitely agree that the current process does not scale to have to add tables when a plugin needs tables to all sites. So you proposed one option to create a shared table that has blog_id as a field so only one table needs to be added. But doesn't that effectively create a hybrid architecture where parts of the data are sharded and parts are not?
> My understanding is that WordPress uses a sharding approach to enable scalability, yet it is recommending to not use sharding for extensions; isn't that contradictory? If sharding is the appropriate architecture for WordPress' tables why is it not the appropriate architecture for plugin's tables?
> Or is this simple a case of "Yes, it's not a great situation but it's all we got at the moment?" And if that is the case, maybe it would make sense to come up with a better solution (i.e. a way that it is possible to add new tables to other blogs without timeout?)
If you've noticed, WordPress itself avoids changing its tables as much as possible. Every time they do, they have to write special code to handle wp.com and its 25 million sites in a scalable upgrade mechanism.
Scaling will always be hard. You just have to determine the best way to support it for your specific custom data. There's plenty of options:
1. Don't use separate tables. This is the best approach, but not feasible in all cases. 2. Use one global table. Works, but if the dataset is large or the number of blogs is large, then sharding may be preferred. 3. One or more tables per site. Scaling this is hard for having to create and/or alter tables. You might be able to get away with a create-when-not-there approach, as long as your check for "not-there" is optimized. If not, then you have to give admins a way to create/upgrade all sites. WordPress does this with a network admin approach, with the upgrade-network functionality, when the tables have to be altered. In this case, avoiding alters is the best policy because of the very-large-sites scaling problems.
> On Jun 28, 2011, at 8:48 AM, Peter Westwood wrote: >> The correct solution is to not have a table per blog in a Multisite install.
>> Your plugin should either work with the existing table structure or introduce a global table because it needs to do something fundamentally different or not expect to work on any reasonably sized multisite install when network activated without manual work to create the tables.
>> Running through a table creation for every blog on a large multisite install is not scalable and is probably not what you need :)
> I've been thinking about this a lot lately as we're exploring building a SaaS using WordPress as a base.
> I definitely agree that the current process does not scale to have to add tables when a plugin needs tables to all sites. So you proposed one option to create a shared table that has blog_id as a field so only one table needs to be added. But doesn't that effectively create a hybrid architecture where parts of the data are sharded and parts are not? > My understanding is that WordPress uses a sharding approach to enable scalability, yet it is recommending to not use sharding for extensions; isn't that contradictory? If sharding is the appropriate architecture for WordPress' tables why is it not the appropriate architecture for plugin's tables?
> Or is this simple a case of "Yes, it's not a great situation but it's all we got at the moment?" And if that is the case, maybe it would make sense to come up with a better solution (i.e. a way that it is possible to add new tables to other blogs without timeout?)
Yes and no.
If we for example take the example of a "subscribe to comments" plugin in a multisite install a table per blog is probably wrong for a number of reasons:
1) You can't do anything clever like digesting all emails across all blogs easily 2) You can't provide a single manage my subscriptions UI if the data is sharded across every blog's tables.
In a large install some data needs to be sharded and some needs to be global which is exactly what WordPress itself does - some of the tables in a multisite install are global - users, usermeta, ...
On Jun 29, 2011, at 5:58 AM, Peter Westwood wrote:
> If we for example take the example of a "subscribe to comments" plugin in a multisite install a table per blog is probably wrong for a number of reasons:
> 1) You can't do anything clever like digesting all emails across all blogs easily > 2) You can't provide a single manage my subscriptions UI if the data is sharded across every blog's tables.
> In a large install some data needs to be sharded and some needs to be global which is exactly what WordPress itself does - some of the tables in a multisite install are global - users, usermeta, ...
That make perfect sense. Yes, some data should definitely be global.
But by the same token won't you agree that some should be site-specific, i.e. a post relationships table or a table for taxonomy meta, for example?
> On Jun 29, 2011, at 5:58 AM, Peter Westwood wrote: >> If we for example take the example of a "subscribe to comments" plugin in a multisite install a table per blog is probably wrong for a number of reasons:
>> 1) You can't do anything clever like digesting all emails across all blogs easily >> 2) You can't provide a single manage my subscriptions UI if the data is sharded across every blog's tables.
>> In a large install some data needs to be sharded and some needs to be global which is exactly what WordPress itself does - some of the tables in a multisite install are global - users, usermeta, ...
> That make perfect sense. Yes, some data should definitely be global.
> But by the same token won't you agree that some should be site-specific, i.e. a post relationships table or a table for taxonomy meta, for example?
If they contain data you don't want to access globally and don't fit the current schema then yes.
I would recommend that any plugin that relies on them is written to do something along the following lines:
1) Create the tables in single site when activated. 2) Create the tables when a new blog is created in multisite 3) Comes with an example script to go back and create the tables for pre-existing multisite blogs.
It just doesn't make sense to try and do the table creation at the point of network activation.
On Jun 29, 2011, at 11:05 AM, Peter Westwood wrote:
> If they contain data you don't want to access globally and don't fit the current schema then yes.
> I would recommend that any plugin that relies on them is written to do something along the following lines:
> 1) Create the tables in single site when activated. > 2) Create the tables when a new blog is created in multisite > 3) Comes with an example script to go back and create the tables for pre-existing multisite blogs.
> It just doesn't make sense to try and do the table creation at the point of network activation.
Thanks for clarifying. I misunderstood and thought you were saying "Don't create per-site tables."