All Projects → PetrGlad → compost

PetrGlad / compost

Licence: EPL-1.0 license
Manage lifecycle of stateful components

Programming Languages

clojure
4091 projects

Projects that are alternatives of or similar to compost

Nationalgeographic
NationalGeographic with Android Architecture Components(Lifecycle) & Kotlin
Stars: ✭ 156 (+940%)
Mutual labels:  lifecycle
Mvvmframe
🏰 MVVMFrame for Android 是一个基于Google官方推出的Architecture Components dependencies(现在叫JetPack){ Lifecycle,LiveData,ViewModel,Room } 构建的快速开发框架。有了MVVMFrame的加持,从此构建一个MVVM模式的项目变得快捷简单。
Stars: ✭ 218 (+1353.33%)
Mutual labels:  lifecycle
angular-webpack-material-lazyload-typescript-starter-template
Angular starter template using typescript, angular-material, ui-router, oclazyload with webpack support.
Stars: ✭ 55 (+266.67%)
Mutual labels:  stateful
Androidbaseframemvvm
Android 组件化 MVVM 框架 基于 Jetpack + Kotlin
Stars: ✭ 169 (+1026.67%)
Mutual labels:  lifecycle
Android Disposebag
Automatically dispose RxJava 2 streams on Android using Lifecycle events.
Stars: ✭ 200 (+1233.33%)
Mutual labels:  lifecycle
Ulfberht
🗡️ A small but powerful & opinionated DI library. Written in Kotlin, and powered by annotation processing.
Stars: ✭ 234 (+1460%)
Mutual labels:  lifecycle
Saber
🏄 帮助你快速使用Android的LiveData与ViewModel,已支持SavedState
Stars: ✭ 143 (+853.33%)
Mutual labels:  lifecycle
MVVMQuick
🚀使用MVVMQuick快速构建您的MVVM结构项目!(Quickly start projects with MVVMQuick!)
Stars: ✭ 23 (+53.33%)
Mutual labels:  lifecycle
Unpeek Livedata
LiveData 数据倒灌:别问,问就是不可预期 - Perfect alternative to SingleLiveEvent, supporting multiple observers.
Stars: ✭ 208 (+1286.67%)
Mutual labels:  lifecycle
react-hooks-lifecycle
⚛️ 🪝 ⏳ React hooks lifecycle diagram: Functional components lifecycle explained
Stars: ✭ 194 (+1193.33%)
Mutual labels:  lifecycle
Disposer
Easily dispose rxJava streams with Android's Lifecycle
Stars: ✭ 176 (+1073.33%)
Mutual labels:  lifecycle
Cluster Lifecycle Manager
Cluster Lifecycle Manager (CLM) to provision and update multiple Kubernetes clusters
Stars: ✭ 200 (+1233.33%)
Mutual labels:  lifecycle
Jetpack Mvvm Scaffold
人生苦短,让脚手架为你节省时间。(目前作为《最佳实践》项目的 Dev 版来优先更新)
Stars: ✭ 239 (+1493.33%)
Mutual labels:  lifecycle
Mvvmarchitecture
An example Android app using Retrofit, Room, LiveData, RxJava2, Paging, Koin and the MVVM pattern with the databinding
Stars: ✭ 160 (+966.67%)
Mutual labels:  lifecycle
LifecycleMvp
No description or website provided.
Stars: ✭ 20 (+33.33%)
Mutual labels:  lifecycle
Atomicpurpleteam
Atomic Purple Team Framework and Lifecycle
Stars: ✭ 155 (+933.33%)
Mutual labels:  lifecycle
Flow
Flow is a Swift library for working with asynchronous flows and life cycles
Stars: ✭ 225 (+1400%)
Mutual labels:  lifecycle
RxComponentLifecycle
Rx binding of new Android Architecture Component Lifecycle
Stars: ✭ 57 (+280%)
Mutual labels:  lifecycle
TeamManagerApp
A sample app structure using the MVVM architecture LiveData, RxJava, ViewModel, Room and the Navigation Arch Components.
Stars: ✭ 36 (+140%)
Mutual labels:  lifecycle
Relax
☘☘Relax 基于Kotlin语言编写的一套组件化框架,不紧整体组件化、内部也高度组件化🎋你可配置MVP、MVVM的开发模式、也可以配置所需要的业务组件🍁🍁
Stars: ✭ 253 (+1586.67%)
Mutual labels:  lifecycle

Compost

Library that manages lifecycle of stateful components. This is a variation of https://github.com/stuartsierra/component project's idea. At the moment this library does not support ClojureScript.

Status

Beta, you are welcome to try it.

Usage

Add this dependency to your project

  [net.readmarks/compost "0.2.0"]

See tests for examples. Component declaration has form

   {:requires #{:required-component-id-1 :required-component-id-2}}
    :this initial-state
    :get (fn [this] ...) ;; Returns value of this component that other components will get as dependency. 
    :start (fn [this dependency-components-map] ...) ;; Acquire resources (open connections, start threads ...)
    :stop (fn [this] ...)} ;; Release resources.

All fields are optional, defaults are:

   {:requires #{}
    :this nil
    :get identity 
    :start (fn [this dependency-components-map] this)
    :stop identity}

:start and :stop functions should return new value of component's :this. If component acquires resources in :start it must release them in :stop. System declaration is a plain map

  {:component-1-id component-1-declaration
   :component-2-id component-2-declaration
   ...
  }

Lifecycle usage example

 (require '[net.readmarks.compost :as compost])
 (let [s (compost/start system-map #{:web-component :some-worker-component})]
   (Thread/sleep 5000)
   (compost/stop s))

You can salvage current system state after exception as follows:

 (try
   (compost/start system-map)
   (catch ExceptionInfo ex
     (if-let [sys (compost/ex-system ex)]
       (compost/stop sys) ;;; Handle this system as desired here.
       (throw ex))))

Error handling helpers

This feature is implemented by net.readmarks.compost.keeper namespace. This namespace is considered experimental, it's contents might change in any version.

The agent ("keeper") holds current state of system along with lifecycle's exceptions. The usage example:

 (require '[net.readmarks.compost :as compost])
 (require '[net.readmarks.compost.keeper :as keeper])

 (def sys (keeper/keeper system-map))

 (keeper/update-keeper! sys compost/start)
 ;; Now sys holds current system value and errors if there are any.
 ;; (:system @sys) is current system map value.
 ;; (:errors @sys) is list of of system lifecycle errors. It is empty if system changes were successful.

 ;; You can send these errors into a log, for example:
 (keeper/flush-errors! sys println) ;; The function gets errors one by one.

Using com.stuartsierra.component components

You can adapt existing components as follows:

(defn component-using [init using]
  {:requires (set using)
   :this init
   :start (fn [this deps]
            (-> (merge this deps)
                component/start)
   :stop component/stop})
 
(def system 
  {:conn-source (component-using
                   (->MyConnPool)
                   [])
   :dao (component-using
          (map->MyDbComponent {})
          [:conn-source])}

Note that unlike com.stuartsierra.component sequence of n.r.compost/stop might differ from reverse startup one. Only explicitly declared dependencies are respected. If you need to account for implicit dependencies you should add additional elements to components' :require collections.

Motivation

I like what com.stuartsierra.component provides but I also want

  • Use any value as component. E.g. often I want a function closure to be a component. Or, alternatively, a component be visible as a function. Besides this, I do not like the idea of always keeping dependency reference even though it might be needed only in start function.
  • Do not require a new type for each component. Implementing Lifecycle gets in the way when you only need an ad hoc component. Also requirement for component to be a map and implement LifeCycle effectively restricts component to be a record. This also means that sometimes people resort to work-arounds to avoid creating new types.
  • Use plain Clojure data structures to configure system. I think that putting configuration into metadata was a mistake. Instead of streamlining it actually complicates code. System configuration is also data that one might want to inspect or modify. Give it equal rights :)
  • Be compatible with com.stuartsierra.component/Lifecycle components. There are already lots of such components and this is a good thing. This part should require only small amount of glue code.

License

Copyright © Petr Gladkikh [email protected]

Distributed under the Eclipse Public License either version 1.0 or (at your option) any later version.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].