Create new driver services to be consumed by managers
Closed this issue · 13 comments
There is a bunch of redundancy between the ActionManager and the Provider with the new ORM provider.
I'm proposing creating a new service level to abstract the storage specific configuration & options called 'drivers'. This would require the following changes…
Remove:
- Dynamic defintions of
highco.timeline_action_manager.*
- Provider classes
highco.timeline.provider.*
Add:
- Drivers
highco.timeline.drivers.doctrine.orm
with an object manager dependency (defaulting todoctrine.orm.entity_manager
highco.timeline.drivers.redis
with a service dependency onsnc_redis.default_client
- Managers
highco.timeline.action_manager.orm
- Depends on
highco.timeline.driver.orm
for persistence
- Depends on
highco.timeline.action_manager.redis
- Depends on
highco.timeline.driver.redis
for persistence
- Depends on
highco.timeline.timeline_manager.orm
- Depends on
highco.timeline.driver.orm
for persistence
- Depends on
highco.timeline.timeline_manager.redis
- Depends on
highco.timeline.driver.redis
for persistence
- Depends on
- Aliases
highco.timeline.timeline_manager
as alias to chosen service from above
Redefine:
highco.timeline.action_manager
as alias to chosen service from abovehighco.timeline.spread.deployer
to depend onhighco.timeline.timeline_manager
highco.timeline.unread_notifications
to depend onhighco.timeline.timeline_manager
This would also support the introduction of a component manager as discussed in #35.
Another issue for 2.0
Possible configuration refactoring to support above:
highco_timeline:
classes:
timeline: 'Acme\YourBundle\Entity\Timeline'
action: 'Acme\YourBundle\Entity\Action'
component: 'Acme\YourBundle\Entity\Component'
action_component: 'Acme\YourBundle\Entity\ActionComponent' # bundle might not need to know this
drivers:
orm:
object_manager: ~ # doctrine.orm.entity_manager
redis:
service: ~ # snc_redis.default_client
action_manager: highco.timeline.action_manager.orm # or user provided
component_manager: highco.timeline.component_manager.orm # or user provided
timeline_manager: highco.timeline.timeline_manager.orm # or user provided
notifiers: [ highco.timeline.unread_notifications ]
filters:
- highco.timeline.filter.duplicate_key
- highco.timeline.filter.data_hydrator
spread:
on_me: true # Spread each action on subject too
on_global_context: true # Spread automatically on global context
deployer: highco.timeline.spread.deployer
delvery: immediate
render:
path: 'AcmeBundle:Timeline'
fallback: 'AcmeBundle:Timeline:default.html.twig'
i18n: #Do you want to use i18n when rendering ? if not, remove this node.
fallback: en
resources: [] # Always prepends 'HighcoTimelineBundle:Action:components.html.twig'
Mmmh issue here is than we cannot use Doctrine ORM/ODM to store Action, Component & co and store Timelines on Redis. In 1.x it's possible. I think to something like that:
highco_timeline:
classes:
timeline: 'Acme\YourBundle\Entity\Timeline'
action: 'Acme\YourBundle\Entity\Action'
component: 'Acme\YourBundle\Entity\Component'
action_component: 'Acme\YourBundle\Entity\ActionComponent' # bundle might not need to know this
drivers: #define drivers
orm:
object_manager: ~ # doctrine.orm.entity_manager
redis:
service: ~ # snc_redis.default_client
# ++++++++++++++
storage:
driver: orm
# ++++++++++++++
action_manager: highco.timeline.action_manager.orm # or user provided
component_manager: highco.timeline.component_manager.orm # or user provided
timeline_manager: highco.timeline.timeline_manager.orm # or user provided
notifiers: [ highco.timeline.unread_notifications ]
filters:
- highco.timeline.filter.duplicate_key
- highco.timeline.filter.data_hydrator
spread:
# ++++++++++++++
driver: orm
on_subject: true # on_subject instead of on_me.
# ++++++++++++++
on_global_context: true # Spread automatically on global context
deployer: highco.timeline.spread.deployer
delvery: immediate
render:
path: 'AcmeBundle:Timeline'
fallback: 'AcmeBundle:Timeline:default.html.twig'
i18n: #Do you want to use i18n when rendering ? if not, remove this node.
fallback: en
resources: [] # Always prepends 'HighcoTimelineBundle:Action:components.html.twig'
One more thing, why don't use many bundles ?
- TimelineBundle (root)
- TimelineDoctrineORMDriverBundle
- TimelineDoctrineODMDriverBundle
- TimelineRedisDriverTimelineBundle
- etc ...
It'll be easy to improve each drivers and user'll have to install only his needs.
And BTW, we could create an organisation, it'll be more convenient.
In my proposal, storing timeline on Redis would be implemented through:
highco_timeline:
timeline_manager: highco.timeline.timeline_manager.redis
Which would essentially be a refactoring of highco.timeline.provider.redis
. The spread deployer would be configured to use the highco.timeline.timeline_manager
alias, and be ignorant of the storage mechanism.
Did I miss something?
Re: separate bundles:
Hmmm, It seems like an unnecessary level of abstraction & overhead. Once implemented will the drivers really change that often?
Re: In my proposal, ..etc...
You're right, we could set alias
for our "core" manager, it would be easier
highco_timeline:
....
drivers: #define drivers
orm:
object_manager: ~ # doctrine.orm.entity_manager
redis:
service: ~ # snc_redis.default_client
action_manager: orm
component_manager: orm
timeline_manager: redis
....
Re: separate bundles:
I took for example SonataAdmin, and yes, it's may be an unuseful layer, leave it as is.
I would recommend keeping the _manager
keys as direct references to driver-specific managers (highco.timeline.action_manager.orm
etc) to allow users to override/extend stock managers as they see fit.
Also, I'm not a huge fan of the Sonata way of doing things.
I noticed you have chosen to go with distinct storage-specific managers Spy\Drivers\ORM\ActionManager
, rather than abstracting the storage access into an abstract layer. Was it not possible to have generic managers working on a common driver api?
Yes, we should use Abstract ActionManager when we have support for ORM and ODM. ODM support will be implemented soon, we could add theses Abstract manager during this implementation ?
If you want to address it to an issue, i think we should create a new. :)
Perhaps I need to review the new code.