LinearBase.Server 0.1.0-beta

This is a prerelease version of LinearBase.Server.
dotnet add package LinearBase.Server --version 0.1.0-beta
NuGet\Install-Package LinearBase.Server -Version 0.1.0-beta
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="LinearBase.Server" Version="0.1.0-beta" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add LinearBase.Server --version 0.1.0-beta
#r "nuget: LinearBase.Server, 0.1.0-beta"
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install LinearBase.Server as a Cake Addin
#addin nuget:?package=LinearBase.Server&version=0.1.0-beta&prerelease

// Install LinearBase.Server as a Cake Tool
#tool nuget:?package=LinearBase.Server&version=0.1.0-beta&prerelease

LinearBase.Server

.NET-as-a-Database - Relational (RDBMS) and Document database functionality miniaturized, containerized, and virtualized and integrated into .NET.

LinearBase.Server adds globally distributed transactional and relational data processing to .NET. The package provides inline Client functionality and Server capability over gRPC. Use in conjunction with the schema generation tools LinearBase.Transform.exe and LinearBase.Model.exe available to download free at LinearBase Downloads

Move data processing out of the database and into collaborative .NET App, Program, and micro-service virtual hosts running on smart-devices, computers, servers, and the cloud, simultaneously. LinearBase.Server invisibly manages processing and distribution within and across participating hosts.

Supports Windows, iOS, Mac, and Linux with Docker-on-Linux for servers. Android not supported (use LinearBase.Client package).

There are no data-contexts, connection strings, or Object Role Mappings (ORM) to manage; configurable profiles control everything.

Hierarchical Read()

// Starting at 1 return up to 5 Invoice.Order records
// Extent defines returned Product, Extent == 1 returns single instance otherwise Collection<T> of instances

// Specify root type to Read<T>(...)
var graph = hcd.Read<Invoice.Order>(
    1, 	// Offset: one based record to start at
	5,	// Extent: number of records to return, maximum is 500
	
	// include optional Where<TN>(...) clause for root type or any nested type including types in modelled 'cross-domain' associations
	// hcd.Where<TN>(nameof(TN.TypeFieldName), Criteria.EqualTo("Some Value")),
		// Include additional And<TN>(...) Or<TN>(...) filters
       	//.And<TN>(nameof(TN.TypeFieldName), Criteria.Between("Lower Value", "Upper Value")) 
       	//.Or<TN>(nameof(TN.TypeFieldName), Criteria.GreaterThan("Some Value")), 
    cncellationToken);

// graph contains paging information and returned binary
_logger.LogInformation("Read returned {count} records. Page {page} of {of} from {from} matches", graph.Paging.Count, graph.Paging.Page, graph.Paging.Of, graph.Paging.From);

// Resolve graph binary using Product<T>() when Read.Extent == 1 otherwise Product<Collection<T>>()
var orders = graph.Product<Collection<Invoice.Order>>();

Transactional Write()

// Any new or updated instance or collection of new and/or updated instances
var instance = new Invoice.Order(...);
var statistics = hcd.Write(instance, cancellationToken);
// returned statistics contains transaction information, statistics.Continuum.Acidity reports outcome: Committed, Failed, RolledBack, and Cancelled
var outcome = statistics.Continuum.Acidity == Reference.Acidity.Committed ? "Write operation successful" : "Write operation failed";
_logger.LogInformation("Statistics returned Continuum.Acidity:{acidity} - {outcome}", statistics.Continuum.Acidity, outcome);	

Realm

Critical to each installation is one or more auto-generated Realms. A Realm describes the domain structure and schemas and defines the transaction boundary.

A Centralized architecture will contain the Realm and all domain Programs hosted on a single Server service. Clients communicate with this service.

A Distributed or Decentralized architecture separates the Realm, Server services, and Clients across individual collaborative hosts. In this situation it is beneficial to create an independent Primary Active Realm Service (PARS) host.

The following suits Distributed and Decentralized architectures.

Configure LinearBase.Server

Configuration profiles control the entire system behaviour.

Each profile describes internal Client data locations, distributed service endpoints (Server services), and individual program settings, e.g. concurrency, consistency, scope, etc.

Server capability 'listens' on the specified PARS port and processes Client requests.

Configuration Profile modifications take effect on App or Program restart.

The LinearBase Transformation and Modelling programs auto-generate:

  • POCO's (plain old CLR objects) representing domain models
  • Generic Host and Service extensions
  • A demonstration console program
  • Design-time and runtime profile initializers including docker-compose.yml

Runtime Server Host Setup

Use the auto-generated initialization scripts to create a single separate Primary Active Realm Service (PARS) instance supporting individual collaborative Client and Server enabled App and Program hosts.

This is the basis of any Distributed or Decentralized architecture.

In this release Port Reuse is enabled by default meaning the PARS Port is replicated across participating Server hosts.

Windows Console

PARS IP is that of the host OS. Port Reuse currently limits implementation to one Server service per Windows OS.

Realm and Program specific auto-generated initialization commands can be found in the CommandLines.txt file in the relevant RealmName folder.

\\<Path To>\LinearBase.Host.exe -a Boot -l "\\<Realm Path>\<RealmName>\<PARSSERV>" -o 60001

Docker-on-Linux

Typically, a Docker container will utilize a Linux mount and docker volume to access centralized Storage Area Network (SAN) or Network Attached Storage (NAS) Single Version of the Truth file locations.

Port Reuse requires individual IP address per container through IPVlan network.

To initialize PARS the suggested command is...

docker run -dti --rm -v "/<your_realm_storage_mount>:/data" \
    -p 60001:60001 \
    --name lineardb-RealmName-PARSSERV \
    --network <YourIpVlanNetwork> \
    --ip <PARS IP Address> \
    -e "HCD_START_ACTION=Boot" \
    -e "HCD_LOAD_URI=/data/<RealmName>/<PARSSERV>" \
    -e "HCD_PARS_PORT=<PARS Port>" \
    -e "HCD_CONTAINER_IP=0.0.0.0" \
    linearbase/lineardb-amd64:latest

To initialize a distributed Server instance to process Client requests...

docker run -dti --rm \
    -p 60001:60001 \
    --name lineardb-G5QHCI1X \
    --network <YourIpVlanNetwork> \
    --ip <Container IP Address> \
    -e "HCD_START_ACTION=Publish" \
    -e "HCD_LOAD_URI=http://<Your PARS IP Address>/<PARSSERV>/<LOADTHIS>" \
    -e "HCD_PARS_PORT=<PARS Port>" \
    -e "HCD_CONTAINER_IP=0.0.0.0" \
    linearbase/lineardb-amd64:latest

The corresponding auto-generated docker-compose.yml file contains...

version: "3"

services:
    hyper-connected-data:
        container_name: linearbase-G5QHCI1X
        image: linearbase/lineardb-amd64:latest
        ports:
            - "<PARS Port>:<PARS Port>"
        restart: always
        tty: true
        networks:
            vlan30:
	                ipv4_address: <Service IP Address>
        environment:
            # !! Update HCD_LOAD_URI to reflect your environment 

            # Distributed Processing - Realm Agent Boot. Initialize & Publish Program within business network & inside firewall, e.g. desktop, Web, tablet, mobile, edge device, DataCentre, etc. Requires accessible PARS instance.
            - HCD_START_ACTION=Publish
            - HCD_LOAD_URI=http://<Your PARS IP Address>/<PARSSERV>/<LOADTHIS>
            - HCD_PARS_PORT=<PARS Port>
            - HCD_CONTAINER_IP=0.0.0.0
            - HCD_CERTIFICATE_URI=

networks:
   vlan30:
     external: true
     name: YourIpVlanNetwork

Design-time Client-Server Host Setup

.NET MAUI Blazor Hybrid App MauiProgram.cs example...

public static class MauiProgram
{
    public static MauiApp CreateMauiApp()
    {
        var builder = MauiApp.CreateBuilder();
        builder
            .UseMauiApp<App>()
            .ConfigureFonts(fonts =>
            {
                fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
            });

        builder.Services.AddMauiBlazorWebView();
        // Reference auto-generated LinearBase Service extension method
        builder.Services.AddLinearBaseService();

#if DEBUG
        builder.Services.AddBlazorWebViewDeveloperTools();
        builder.Logging.AddDebug();
#endif

        builder.Services.AddSingleton<YourCustomService>();

        return builder.Build();
    }
}

Auto-generated LinearBaseServiceExtension AddLinearBaseService(...) method reads and deploys the relevant configuration profile.

Create Hyper-Connected Data singleton and Publish one or more Profiles...

// Auto-generated code
public static class AddLinearBaseServiceExtension
{
    public static IServiceCollection AddLinearBaseService(this IServiceCollection services)
    {
		//Lazy load, initialized on Hcd first use. Create Startup initializer
		
		services.AddSingleton<IHcd>(provider =>
		{
			ILoggerFactory? loggerFactory = null;
			ILogger? logger = null;
			IHcd? hcd = null;

			try
			{
				#region loggerFactory

				loggerFactory = provider.GetService<ILoggerFactory>();
				if (loggerFactory == null)
				{
					Console.WriteLine(@"Launch aborted, ILoggerFactory not a service, terminating launch process!");
					return new Hcd(new LoggerFactory());
				}

				logger = loggerFactory.CreateLogger("AddLinearBaseService");

				#endregion

				#region Create & Publish

				hcd = new Hcd(loggerFactory);

				if(!hcd.Active)
				{
					logger.LogWarning("Unable to activate HCD service");
					return hcd;
				}

				logger.LogInformation("Publish Hyper-Connected Data service...");

				hcd.Publish(new Uri(@"http://<Your PARS IP Address>/PARSSERV/LOADTHIS"), <PARS Port>, CancellationToken.None);
				
				// Optionally publish multiple Profiles
				//hcd.Publish(...);
				//hcd.Publish(...);

			}
			catch (Exception e)
			{
				logger?.LogError(e, "Publish Hyper-Connected Data service failed");
			}

			#endregion

			return hcd ?? new Hcd(loggerFactory);
		});

        return services;
    }
}
Product Compatible and additional computed target framework versions.
.NET net7.0 is compatible.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
0.1.0-beta 47 5/22/2024

Initial 0.1.0 beta release