Picos are persistent compute objects. Persistence is a core feature that distinguishes picos from other programming models. Picos exhibit persistence in three ways:
Persistent identity—Picos exist, with a single identity, continuously from the moment of their creation until they are destroyed.
Persistent state—Picos have persistent state that programs running in the pico can see and alter. The state is is isolated and only available inside the pico.
Persistent availability—Once a pico is created, it is always on and ready to process queries and events.
Persistent identity, state, and availability make picos ideal for modeling entities of all sorts. Applications are formed from cooperating networks of picos, creating systems that better match programmer’s mental models. Picos employ the actor model
abstraction for distributed computation. Specifically, in response to a received message, a pico may
- send messages to other picos—Picos respond to events and queries by running rules. Depending on the rules installed, a pico may raise events for itself or other picos.
- create other picos—Picos can create child picos and delete them.
- change its internal state (which can affect their behavior when the next message is received)—Each pico has a set of persistent variables that can only be affected by rules that run in response to events.
In addition to the parent-child hierarchy, picos can be arranged in a heterachical network for peer-to-peer communication and computation. A cooperating network of picos reacts to messages, changes state, and sends messages. Picos have an internal event bus for distributing those messages to rules installed in the pico. Rules in the pico are selected to run based on declarative event expressions
. The pico matches events on the bus with event scenarios declared in each rule’s event expressions. Any rule whose event expression matchs is scheduled for execution. Executing rules may raise additional events. More detail about the event loop and pico execution model
are available elsewhere.
Here are ten reasons picos are a great development environment for building decentralized applications:
Picos can be a computational node that represents or models anything: person, place, organization, smart thing, dumb thing, concept, even a pothole. Because picos encapsulate identity and state, they can be used to easily model entities of all types.
Picos use a substitutable hosting model. Picos are hosted on the open-source pico engine. Picos can be moved from pico engine to pico engine without loss of functionality or a change in their identifying features1. More importantly, an application built using picos can employ picos running on multiple engines without programmer effort.
Pico-based applications are scalable. Picos provide a decentralized programming model which ensures that an application can use whatever number of picos it needs without locks or multi-threading. Pico-based applications are fully sharded, meaning there is a computational node with isolated state for every entity of interest. Because these nodes can run on different engines without loss of functionality or programmer effort, pico-based applications scale fluidly. Picos provide an architectural model for trillion-node networks where literally everything is online. This provides a better, more scalable model for IoT than the current CompuServe of Things.
Picos can provide high availability in spite of potentially unreliable hosting. Multiple picos, stored in many places can be used to represent a specific entity. Picos modeling a popular web page, for example, could be replicated countless times to ensure the web page is available when needed with low latency. Copies would be eventually consistent with one another and no backups would be needed.
Picos are naturally concurrent without the need for locks. Each pico is an island of determinism that can be used as a building block for non-determinant decentralized systems. Each pico is isolated from any other pico, asynchronous processing is the default, and facts about the pico are published through protocols. State changes are determined by rules and respond to incoming messages seen as events. This minimizes contention and supports the efficient use of resources.
Picos provide a cloud-native (internet-first) architecture that matches the application architecture to cloud model. The pico programming model lets developers focus on business logic, not infrastructure. Applications built with picos don’t merely reside in the cloud. They are architected to be performant while decentralized. Picos support reactive programming patternsthat ensure applications are decoupled in both space and time to the extent possible.
Picos enable stateful, databaseless programming. Picos model domain objects in code, not in database tables. Developers don’t waste time setting up, configuring, or maintaining a database. Each ruleset forms a closure over the set of persistent variables used in it. Programmers simply use a variable and it is automatically persisted and available whenever a rule or function in the ruleset is executed.
Picos use an extensible service model where new functionality can be layered on.Functionality within a pico is provided by rules that respond to events. An event-based programming model ensures services inside a pico are loosley coupled. And isolation of state changes between services (implemented as rulesets) inside the pico ensure a new service can be added without interfering with existing services. An event can select new rules while also selecting existing rules without the programmer changing the control flow2.
Picos naturally support a Reactive programming model. Reactive programming with picos directly addresses the challenges of building decentralized applications through abstractions, programming models, data handling, protocols, interaction schemes, and error handling3. In a pico application, distribution is first class and decentralization is natural. You can read more about this in Building Decentralized Applications with Pico Networks and Reactive Programming Patterns: Examples from Fuse.
Picos provide better control over terms, apps, and data. This is a natural result of the pico model where each thing has a closure over services and data. Picos cleanly separate the data for different entities. Picos, representing a specific entity, and microservices, representing a specific business capability within the pico, provide fine grained control over data and its processing. For example, if you sell your car, you can transfer the vehicle pico to the new owner, after deleting the trip service, and its associated data, while leaving untouched the maintenance records, which are stored as part of the maintenance service in the pico.
And a bonus reason for using picos:
Picos provide a better model for building the Internet of Things. Picos are an antedote to the CompuServe of Things because they provide a scalable, decentralized model for connecting everything. We built a connected car platform called Fuse to prove this model works (read more about Fuse). Picos are a natural building block for the self-sovereign internet of things (SSIoT)and can easily model necessary IoT relationship. Picos create an IoT architecture that allows interoperable interactions between devices from different manufacturers.
If you’re intrigued and want to get started with picos, there’s a Quickstart
along with a series of lessons
. If you need help or just want to talk about picos, contact me
and we’ll get you added to the Picolabs Slack. We’d love to help you use picos for your next distributed application.
- The caveat on this statement is that pico engines currently use URLs to identify channels used for inter-pico communication. Moving to a different engine could change the URLs that identify channels because the domain name of the engine changes. These changes can be automated. Future developments on the roadmap will reduce the use of domain names in the pico engine to make moving picos from engine to engine even easier.
- Note that while rules within a ruleset are guaranteed to execute in the order they appear, rules selected from different rulesets for the same event offer no ordering guarantee. When ordering is necessary, this can be done using rule chaining, guard rules, and idempotence.
- I first heard this expressed by Jonas Bonér in his Reactive Summit 2020 Keynote.