If you have been following this blog series discussing Enterprise Conversation Applications, we have touched upon several interesting topics thus far. We have dissected what makes an Enterprise Architecture enterprise-y, announced an off-the-shelf Enterprise Conversation Implementation, and chewed over the storage considerations during deployment.
This blog post will unlock the real potential of why this Enterprise Reference Implementation is exceptional. The secret sauce in the implementation is this idea of a Plugin-based Conversation architecture. We have danced around this topic in previous blog posts for a while. Now is the perfect time to do a deep dive into this mic-dropping capability and unveil the Enterprise Conversation Plugins repo.
Extensible Conversation Application via Plugins
In software development, there are always countless things we write code for time and time again. The industry devised solutions for this problem by creating libraries or reusable code that we could reference or drop into the codebase. This reduces the need to write the same code repeatedly while decreasing time spent on maintenance and increasing robustness through reuse. We have taken a page from that book by implementing that design goal in a non-obvious way; hence this blog post.
Because the project uses RabbitMQ to handle the notifications for events happening within the system, we will leverage that same system to pull off the interface to the plugin framework. RabbitMQ can fan out or broadcast messages to anyone subscribing to specific notifications. A high-level depiction of what that might look like is pictured below.
That brings us to the Enterprise Conversation Plugins repo. This repo intends to offer an “App Store”-like experience where people can take advantage of generic pre-built functionality. By launching a plugin within the repo, you can surface messages, create triggers, etc., within your application. There are currently two plugins within the repo, a historical and a statistical plugin, that offer exceptional capabilities and can be dropped into your application today.
Watch the following video demo to learn more:
How Do I Create a Conversation Plugin?
You might be saying, “This is pretty amazing—how do I create my own plugin?” Well, I’m glad you asked, because that’s what we will address next.
In the Enterprise Reference Implementation repo, a Plugin SDK offers up the plugin interfaces required to implement. The plugin interface is pretty simple:
/*
This implementer of this interface handles much of the routing to your middleware-analyzer component
As Symbl insights are received from the platform, these callbacks will be invoked
*/
type InsightCallback interface {
/*
This ensures there is a 1-to-1 mapping between insights the Symbl Platform provides and
which events are possible to be notified to
*/
sdkinterfaces.InsightCallback
/*
The Client Publisher interface will be set before messages trigger functions in the
sdkinterfaces.InsightCallback
*/
SetClientPublisher(mp *MessagePublisher)
}
You might be asking, what is SetClientPublisher(*MessagePublisher) used for? That command will pass a pointer to the struct that implements the MessagePublisher interface, which allows your Conversation Plugin to pass named application-specific messages to your UI or client.
/*
This provides an interface for the implementing struct to sent messages to the client.
*/
type MessagePublisher interface {
PublishMessage(name string, data []byte) error
}
Is there an example code/scaffolding for a plugin that could be used as a starting point? The answer is: most definitely. In the Example Middleware Plugin folder, there is an example Conversation Plugin that passes a simple application-specific message for every possible Symbl.ai Platform message to your UI or client. Then, to test out your plugin’s application-specific message implementation, you can use the Example Simulated Client App to ensure your UI will receive your messages when you finally implement that piece of your application.
Plugin Advanced Topics
I wanted to mention some advanced Conversation Plugin topics that might be of value to you. The first is how to scale out your plugin instances, and, finally, how to have your plugins talk to each other.
Scaling Out Your Plugin Instances
If you haven’t noticed yet, the Conversation Plugin’s architectural design is actually that of a Microservice. This is great news because we can containerize our plugins (coming soon to a GitHub action near you), and you can also scale out your plugin if you use a container orchestrator such as Kubernetes. If your plugin would benefit from scaling for reasons including pegging the CPU, memory requirements, etc., this is an effective solution.
One possible and effortless way this could be done is by dividing up the work based on the conversation UUID. For example, if you know through profiling that the response time has passed the threshold and is increasing exponentially within your plugin, you could scale to two instances. Then divide the work by allocating conversations UUIDs starting with 0-7 to plugin instance No. 1 and UUIDs starting with 8-F to plugin instance No. 2.
Of course, the best way is to use a modern scheduler such as Kubernetes or have a proxy service that dispatches or redirects requests to instances based on round robin or, better yet, by instance load if you are capturing metrics on your services. Too many ways!
Internal Communication Between Plugins
Another great concept we can implement is having Conversation Plugins talk to other conversation plugins. Why might you want to do this?
Some of those reasons might be but are not limited to:
- Complex workflows or business logic
- Separation of concerns
- different teams working on different microservices
- Interfacing with other platforms or systems
- Aggregation of plugins messages and/or data
- Creating a higher-level message that needs more metadata
I want to call out that last reason, creating a higher-level message that needs more metadata, because it’s probably the one you will run into most often. The Conversation Plugins within the repo are intended to be generic and void of any company-specific business rules or logic. Still, you might want the information supplied by one plugin and add more of your (meta)data or context around it.
For example, you might use the statistical plugin to collect information about how many times a particular Tracker has come up in the past hour. If that number exceeds ten mentions, you might want to send a Slack message to a specific channel to investigate. All you would need to do is create a new Conversation Plugin that subscribes to the Statistics metrics (seen here and shown in the above diagram as the green arrow) from the statistical plugin. Your implementation would be limited to sending a Slack message when that value is greater than 10 and maybe a notification to the UI, if needed.
Bring It All Together
We have now discussed several remarkable things about this Enterprise Reference Implementation and the idea of having a community repository for Conversation Plugins that everyone can use. This Conversation Plugins repo is for others to be able to contribute different kinds of functionality that the community could use. Said a little differently… we would be excited to take any pull requests for plugins!
Many people have been interested in security as it pertains to various architectures and implementations for these Conversation Applications. So, we are going to tackle that topic in the next blog post. Talk to you then!