metagov / gateway

An API gateway for online communities
https://docs.metagov.org/
MIT License
49 stars 16 forks source link

Storing arbitrary "governance documents" in Plugin state #16

Closed gigxz closed 3 years ago

gigxz commented 3 years ago

Each Plugin has a one-to-one relationship with a state model, which is just a datastore that can be used to store any data for the life of the plugin. (Life of the plugin = from when it's activated for the community, until it's deactivated or the community is deleted). I originally added this because I wanted to store data that was fetched on initialization so that it can be accessed later on. I was thinking of state as something that can be re-created on plugin init.

HOWEVER, I realized I could just use the state to support the web monetization revshare use-case. Here's how: https://github.com/metagov/metagov-prototype/blob/2eb8931212ed705fff3de382d1f8943d700530f4/metagov/metagov/plugins/webmonetization/models.py

Instead of the actions performing actions on an external platform, the actions are updating the state of the plugin itself. Instead of the resource functions getting data from an external platform, the resource functions are returning data from the plugin state.

I think this is a fine approach to use for small structured documents. I don't think we need to go beyond this right now. If we see it being repeatedly used in a common way, maybe we'll want to add an abstraction specifically for creating/updating/deleting structured documents.

Q&A about using plugin state to store "documents":

1. Can the Driver govern changes to the document?

Yes. In the revshare example, the document is changed by invoking a metagov action (eg POST /api/internal/action/webmonetization.remove-pointer). Only the Driver is able to invoke that request, so, naturally the Driver can "govern" that action however it wants to.

2. Can the Driver govern access to the document?

Same as (1) –– the Driver is the only thing that can access the /resource endpoint, so yes. Unless...

3. Can we allow public access to the document?

This is really a separate issue. As mentioned on https://github.com/metagov/metagov-prototype/issues/15 we are considering making all /resource endpoints totally public, or allowing plugin authors to declare whether resources are public (anyone on internet) or private (driver only).

Changes to make:

Currently we destroy and re-create the plugin (and its state) whenever the plugin config changes (code). Instead of deleting and recreating plugin instances, we should have plugin authors implement apply_config or some pre-save hook that lets them choose what to do when the config changes. Likewise, we should just mark the plugin instance as inactive when a community deactivates it, instead of deleting the instance.

thelastjosh commented 3 years ago

Excellent.

I think this is a fine approach to use for small structured documents. I don't think we need to go beyond this right now. If we see it being repeatedly used in a common way, maybe we'll want to add an abstraction specifically for creating/updating/deleting structured documents.

Agreed.

Let's make sure this gets in to the documentation at some point.

On Fri, Mar 26, 2021 at 4:00 PM Miriam Ashton @.***> wrote:

Each Plugin has a one-to-one relationship with https://github.com/metagov/metagov-prototype/blob/2eb8931212ed705fff3de382d1f8943d700530f4/metagov/metagov/core/models.py#L63-L67 a state model, which is just a datastore that can be used to store any data for the life of the plugin. (Life of the plugin = from when it's activated for the community, until it's deactivated or the community is deleted). I originally added this because I wanted to store data that was fetched on initialization https://github.com/metagov/metagov-prototype/blob/2eb8931212ed705fff3de382d1f8943d700530f4/metagov/metagov/plugins/opencollective/models.py#L51 so that it can be accessed later on. I was thinking of state as something that can be re-created on plugin init.

HOWEVER, I realized I could just use the state to support the web monetization revshare use-case. Here's how: https://github.com/metagov/metagov-prototype/blob/2eb8931212ed705fff3de382d1f8943d700530f4/metagov/metagov/plugins/webmonetization/models.py

Instead of the actions performing actions on an external platform, the actions are updating the state of the plugin itself. Instead of the resource functions getting data from an external platform, the resource functions are returning data from the plugin state.

I think this is a fine approach to use for small structured documents. I don't think we need to go beyond this right now. If we see it being repeatedly used in a common way, maybe we'll want to add an abstraction specifically for creating/updating/deleting structured documents.

Q&A about using plugin state to store "documents":

1. Can the Driver govern changes to the document?

Yes. In the revshare example, the document is changed by invoking a metagov action (eg POST /api/internal/action/webmonetization.remove-pointer). Only the Driver is able to invoke that request, so, naturally the Driver can "govern" that action however it wants to.

2. Can the Driver govern access to the document?

Same as (1) –– the Driver is the only thing that can access the /resource endpoint, so yes. Unless...

3. Can we allow public access to the document?

This is really a separate issue. As mentioned on #15 https://github.com/metagov/metagov-prototype/issues/15 we are considering making all /resource endpoints totally public, or allowing plugin authors to declare whether resources are public (anyone on internet) or private (driver only). Changes to make:

Currently we destroy and re-create the plugin (and its state) whenever the plugin config changes (code https://github.com/metagov/metagov-prototype/blob/2eb8931212ed705fff3de382d1f8943d700530f4/metagov/metagov/core/serializers.py#L40-L49). Instead of deleting and recreating plugin instances, we should have plugin authors implement apply_config or some pre-save hook that lets them choose what to do when the config changes. Likewise, we should just mark the plugin instance as inactive when a community deactivates it, instead of deleting the instance https://github.com/metagov/metagov-prototype/blob/2eb8931212ed705fff3de382d1f8943d700530f4/metagov/metagov/core/serializers.py#L82-L83 .

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/metagov/metagov-prototype/issues/16, or unsubscribe https://github.com/notifications/unsubscribe-auth/ACHA5PG5JTRE73UC2DRHQRTTFTRUXANCNFSM4Z4AHT3Q .

-- http://www.joshuatan.com/research/

gigxz commented 3 years ago

Alright, I'll plan on making the proposed changes to the plugin lifecycle, and adding it to the documentation.

gigxz commented 3 years ago

Closing this issue, and opened https://github.com/metagov/metagov-prototype/issues/39 for the work required to change the plugin lifecycle. I decided to defer this because we don't have a strong need for it right now.