OOLOI.ORG
Menu

Architectural decision Record 0007: NIPPY

​ADR-0007: Use of Nippy for File Persistence

Picture
Decision: Use Nippy for file persistence in FrankenScore, leveraging its built-in features and implementing custom handlers for FrankenScore's specific needs.

Context:
  • FrankenScore deals with complex musical structures that form a Directed Acyclic Graph (DAG) with shared structure.
  • The system needs to efficiently serialize and deserialize large musical scores.
  • The persistence mechanism should support handling large files efficiently.
  • Concurrent serialization of multiple pieces is desirable for performance.
  • The system should be able to handle future extensions and modifications to data structures.

Rationale:
1. Simplicity and Ease of Use: Nippy provides a simple API that's easy to use out of the box, requiring minimal configuration for basic use cases.

2. Built-in Support for Clojure Data Structures: Nippy is designed specifically for Clojure and has native support for all Clojure data structures, including records and protocols.

3. Performance: Nippy shows excellent performance for Clojure-specific use cases, as it's optimized for Clojure data structures and use patterns.

4. Active Maintenance: Nippy is actively maintained and updated, ensuring ongoing support and improvements.

5. Compression: Nippy includes built-in compression options, which can be very useful for reducing the size of serialized data, especially important for large musical scores.

6. Encryption Support: Nippy offers built-in support for data encryption, which may be useful for future security requirements.

7. Community Adoption: Nippy has wide adoption in the Clojure community, providing ample resources, examples, and community support.

8. Flexibility: Nippy allows for easy extension with custom data types, crucial for our complex musical data structures.

Why Fressian Was Not Chosen

While Fressian was initially considered due to its language-agnostic nature and handling of complex data structures, it was ultimately not selected for the following reasons:

1. Complexity: Fressian requires more configuration and custom coding for basic use cases compared to Nippy's simpler API.

2. Clojure-specific Optimization: While Fressian is language-agnostic, it lacks the Clojure-specific optimizations that Nippy provides, potentially leading to lower performance for our use case.

3. Community Support: Fressian has less community adoption in the Clojure ecosystem, which could lead to fewer resources and examples for complex use cases.

4. Maintenance: Fressian has seen less active maintenance compared to Nippy, which could be a concern for long-term support and improvements.

5. Built-in Features: Nippy offers built-in compression and encryption, which would require additional implementation if using Fressian.

6. Performance: In our specific use case with Clojure data structures, Nippy often outperforms Fressian.

Consequences:
Pros:
  • Simple API and seamless integration with Clojure projects.
  • Efficient handling of Clojure-specific data structures.
  • Built-in compression options for managing large data sets.
  • Active maintenance and strong community support.
  • Excellent performance in Clojure-specific use cases.
  • Built-in encryption support for potential future security needs.

Cons:
  • Clojure-specific, which may limit interoperability with non-JVM systems if needed in the future.
  • Doesn't natively handle shared structure, requiring custom solutions for FrankenScore's musical structures.

Implementation Approach:
  1. Utilize Nippy's core functions for basic serialization and deserialization.
  2. Create a system to handle shared structure using Vector Path Descriptors (VPDs).
  3. Implement asynchronous serialization using Clojure futures for concurrent operations.
  4. Integrate with the Piece Manager for efficient piece storage and retrieval.
  5. Implement chunked serialization and deserialization for handling very large musical scores.
​
Future Considerations:
  • Implement versioning for serialized data to manage future schema changes.
  • Optimize compression settings for very large scores.
  • Develop a comprehensive testing suite for serialization/deserialization, especially for complex structures and shared structure.
  • Monitor performance and optimize as necessary, potentially implementing lazy loading for large scores.
  • Consider implementing a caching mechanism for frequently accessed pieces or sections.
Home
​Overview
Documentation
About
Contact
FrankenScore is a modern, open-source music notation software designed to handle complex musical scores with ease. It is designed to be a flexible and powerful music notation software tool providing professional, extremely high-quality results. The core functionality includes inputting music notation, formatting scores and their parts, and printing them. Additional features can be added as plugins, allowing for a modular and customizable user experience.​
  • Home
  • Overview
    • Background and History
    • Project Goals
    • Introduction for Musicians
    • Introduction for Programmers
    • Introduction for Anti-Capitalists
    • Technical Comparison
  • Documentation
    • Architectural Decision Log >
      • Choice of Clojure
      • Separation of Frontend and Backend
      • Adoption of gRPC
      • Plugins
      • STM for Concurrency
      • JavaFX & Skija
      • SMuFL
      • Nippy
      • Vector Path Descriptors
      • Collaborative Features
      • Trees and Circles
      • Shared Structure
      • Persisting Pieces
      • Slur Formatting
    • Backend src README
    • Development Plan
    • License
    • Code of Conduct
  • About
  • Contact
  • Home
  • Overview
    • Background and History
    • Project Goals
    • Introduction for Musicians
    • Introduction for Programmers
    • Introduction for Anti-Capitalists
    • Technical Comparison
  • Documentation
    • Architectural Decision Log >
      • Choice of Clojure
      • Separation of Frontend and Backend
      • Adoption of gRPC
      • Plugins
      • STM for Concurrency
      • JavaFX & Skija
      • SMuFL
      • Nippy
      • Vector Path Descriptors
      • Collaborative Features
      • Trees and Circles
      • Shared Structure
      • Persisting Pieces
      • Slur Formatting
    • Backend src README
    • Development Plan
    • License
    • Code of Conduct
  • About
  • Contact