mardi 14 novembre 2023

Business validation rules and microservices

We have a microservice architecture, with one of those services being a user service, and another being a calendar service. The problem I am being faced with is this. We have users, and users have products and features. Products are simply bags of features and all of this information is stored in the user service. When selecting a user to display as a potential candidate to place on the calendar, we need to determine if the person being selected has a specific feature turned on. For this, the UI queries the user service and asks for this information and all is well. The trouble in my head comes when we then submit a post request to the calendar service to add the individual to the calendar. How should the calendar service verify that the person who was selected has the specified feature enabled? Should it call directly to the user service and ask, which would introduce coupling but centralize the logic in the service that owns the data? Or should I leverage our service bus and use event carried state transfer to make the user, product, and feature information available to the calendar service? We have several services like this, and it seems like that would be very inefficient for every service to need a copy of the user table and all of their associated products and features, but that seems to be the path of least coupling. Any thoughts or ideas?

lundi 13 novembre 2023

headfirst design pattern, does abstract factory pattern inherently employs factory pattern?

I've read through this article. What are the differences between Abstract Factory and Factory design patterns?

but I still have some uncertainty regarding the Abstract Factory Pattern. My question is whether the Abstract Factory Pattern inherently employs the Factory Design Pattern as a part of its implementation. I'd like to understand if the Abstract Factory Pattern typically incorporates the Factory Pattern for creating its related objects, and if so, how these two patterns are interconnected in practice.

Right architecture for implementing a performance class

I'm creating a library in C++ which has a class with statistical test methods. I also want to write another class that has a set of performance tests over it (like time taken to do a test), but I wonder if I'm doing this the right way, for best performance and reusability.

I have class with the statistical methods (uniformnistanalysis.cpp), a class that is the "test environment" that encapsulates and calls those statistical tests (performance.cpp) with a number n of runs, and checks for the execution time of the function. I want to implement more performance tests but I want first to be sure that the code architecture is fine and hear about other possible arrangements.

Note: performance has an inner class called Timer that counts the execution time of the function for n runs, but as n increases, the average time decreases considerably - and shouldn't, since I'm taking the average of the time of N-runs for the function and then dividing by n. It's going from ~350ns (for n=1) to ~35ns (for n=1000000)

My code structure is:

uniformnistanalysis:

class UniformNISTAnalysis {
    public:
        bool monobit(const DynamicBitset&, double = 0.1);
}

performance.hpp:

class Performance {
public:
    void testMonobit(UniformNISTAnalysis&, const DynamicBitset&, const size_t);
    // more tests will be here...
protected: 
    class Timer {
        public:
            Timer(const std::string&, size_t);
            ~Timer();
        private:
            std::string functionName;
            size_t runs;
            std::chrono::steady_clock::time_point start;
    };
}

parts of performance.cpp:

void TestEnvironment::testMonobit(UniformNISTAnalysis& analysis, const DynamicBitset& bitset, const size_t runs = 1) {
    printTestHeader("Monobit [Mon]");

    bool status;

    // print result
    std::cout << "Number: " << bitset << std::endl;
    std::cout << "Ones: " << bitset.countOnes() << "; Zeroes: " << bitset.countZeroes() << std::endl;
    std::cout << "Ratio of 1s: " << bitset.countOnes() / static_cast<double>(bitset.numBits) << std::endl;

    {
        Timer timer("Monobit", runs);
        for(size_t i = 0; i < runs; i++)
            status = analysis.monobit(bitset);
    }

    printTestStatus("Monobit", status);
}

TestEnvironment::Timer::Timer(const std::string& name, const size_t runs = 1) : functionName(name), runs(runs) {
    start = std::chrono::steady_clock::now();
}

TestEnvironment::Timer::~Timer() {
    auto stop = std::chrono::steady_clock::now();
    auto duration = std::chrono::duration_cast<std::chrono::nanoseconds>(stop - start);
    std::cout << runs << " test(s) '" << functionName << "' took an average of " << duration.count() / static_cast<double>(runs) << "ns to execute." << std::endl;
}

Calling example:

Performance testEnv;
UniformNISTAnalysis analysis;

testEnv.testMonobit(analysis, bitset, 100000);

samedi 11 novembre 2023

Finding the best placement of two black and white images to maximize the similarity

I am looking for an algorithm that would allow me to have the optimal displacement of an image on another (only in 2D x and y, no need for rotation) to find the maximum common pixel (pixel black if on white background and vice versa).

Comparing all the pixels, then redoing the same algorithm by sliding image x+1,y+1 etc. is too time-consuming.. (but works perfectly)

I've thought of comparing 1-2 columns where there's a lot of relief with the image, which would increase speed but doesn't seem optimal.

Also thought of transforming the reliefs into points and then trying to make the best correlation by moving this cloud.

If you have any solutions, I'd love to hear them!

How to implement a Maker Checker in a foreign exchange application

I am currently working on a foreign exchange application whereby a user can make transactions to different countries. For each currency i was able to implement rate limit which means a user cannot transfer more than a daily limit,there’s an admin dashboard where an admin can configure limit for users,but the issue here is that i don’t want an admin to effect a change, admin can only propose a change, then the super admin can accept the proposal. How do i implement this concept.

I use Nextjs for the frontend and Java for the backend

jeudi 9 novembre 2023

Scalable and easy to manage background Processing Java

We have a monolith JAVA application which we are starting to re-write and possibly break down into smaller services. The application has all the REST APIs to power the UI. The application also has a number of background threads that start on application startup.

For example there are three single thread executers that are responsible for doing totally independent set of tasks.

These background jobs mostly are data pipelines. The database access layer is very poorly designed (currently) and are intertwined within the monolith, hence limiting different options.

The major issue we have seen with this setup is that it is non-scalable - Since these background jobs all operate within the main application, we have limited the number of parallel executions, to make sure the main application is not impacted.

For the new application, we will be using Java and Springboot.

[Separate note] We are using airflow for a separate pipeline, however we are trying to get away from it due to operational constraints. So trying to stay away from cloud solutions for now (but suggestions are welcomes)

What are the ways/best practices to design these use cases?

C++ Program Keeps Crashing Without Specific Error [closed]

I am trying to implement an Observer/Subject design pattern between multiple classes. My compiler keeps returning to me the following:

[Done] exited with code=3221225477 in 0.603 seconds.

I assumed this was a success, until I realized nothing worked. I found out (through commenting and uncommenting code) that the crash occurs in 2 places, either when I try to attach an Observer to a child class of Subject, or when I try to call the notify method (which in turn updates the observer). Furthermore, as you will see, the LogObserver default constructor (Child class of Observer), should create and open a file called "gamelog.txt", but fails to do even that. I am not receiving any specific error message, so I dont know why it is crashing or where it is going wrong. Any and all help debugging this?

I'll show the code for the relevant .h and cpp files here, what I expected was for a file to be created, for the observer to be attached to OrderList (child class of Subject), and finally for the text file to be written to upon adding and order to orderlist (which should trigger the Notify method).

Here is the main driver:

#include "LoggingObserver.h"
#include "Orders.h"



void testLoggingObserver(){
    //3 main issues
        //1: File is NOT created upon logObserver default constructor
        //2: The Attach method seems to crash the program
        //3: Keep receiving error for "unidentified reference" to methods 

    //create instances of classes
    LogObserver* logObserver;
    OrdersList * orderList;

    //CRASHES HERE
    //Add the observer to the subjects
    orderList->Attach(logObserver);

    //CRASHES HERE
    orderList->addOrder(new DeployOrder());
}

int main(){
    
    testLoggingObserver();
    cout<<"LogObserver Default Here!"<<endl;
    return 0;
}

Here is the Header for LoggingObserver:

#pragma once
#include <iostream>
#include <vector>
#include <fstream>
#include <set>
#include <algorithm>
#include <list>
#include <iterator>
#include <string>

using namespace std;

//An Interface ILoggable. This interface will be inherited by all classes that can be the subject
//of the logging mechanism
#ifndef I_LOGGABLE_HPP
#define I_LOGGABLE_HPP
class ILoggable{
    public:
        //virtual ~ILoggable();
        //Will create and return a string to be output to the log file
        virtual string stringToLog()=0;
};
#endif

//#ifndef SUBJECT
//#define SUBJECT
class Observer;

//Subject Class will have a list of Observers and methods to add/remove and notify observers
class Subject{
    private:
        //list of Observers
        list<Observer*> *observers;

    public:
        //default contructor and destructor
        //Subject();
        //~Subject();
        
        //Methods to add, remove, and notify Observers
        virtual void Attach(Observer* o)=0;
        virtual void Detach(Observer* o)=0;
        virtual void Notify()=0;

        //friend classes
        friend class GameEngine;
        friend class OrdersList;
        friend class Order;
        friend class Command;
        friend class CommandProcessor;
};
//#endif

//#ifndef OBSERVER
//#define OBSERVER
//Observer Class will have a method to update the state of the observer
class Observer{
    private:

    public:
        //destructor
        ~Observer();
        //method to update state of observer
        virtual void Update(Subject* subject) = 0;
    
    protected:
        //default constructor
        //Observer();
};
//#endif


//#ifndef LOG_OBSERVER
//#define LOG_OBSERVER
class GameEngine;


//This class will override the update method to write the state of the subject to the log file
class LogObserver: public Observer{
    private:
        //file to write to
        ofstream logFile;
        
        //variables attributed to phase
        string playerName;
        string phaseName;
        //GameEngine* subjectGameEngine;

        //variables attributed to game statistics
        int totalContinents;
        bool winnerStatus;
        string conqueredContinent;

    public:
        LogObserver();
        //LogObserver(GameEngine* aSubjectEngine);
        ~LogObserver();
        //update method
        void Update(Subject* subject) override;

        //To display player information and current pahse information
        void logToGameLog(const string& logEntry);

};
//#endif

Here is the .cpp for LoggingObserver:

#include <fstream>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <list>
#include <algorithm>

#include "LoggingObserver.h"

using std::vector;
using std::list;

//Below we will implement all the abstract functions we declared in the previous LogginObserver.h Header File

//========================================ILoggable Class======================================
//Default constructor



//========================================Subject Class======================================
//Default constructor
/*
Subject::Subject(){
    observers = new list<Observer*>;
}


//destructor
Subject::~Subject(){
    delete observers;
}
*/
/*
//Implementation of Add method (adds an observer to the observers list)
void Subject::Attach(Observer* o){
    observers->push_back(o);
}

//Implementation of Remove method (removes an observer from the observers list)
void Subject::Detach(Observer* o){
    observers->remove(o);
}

//Implementation of the Notify method (will call on the observers update method)
void Subject::Notify(){
    list<Observer*>::iterator i = observers->begin();
    for(;i != observers->end(); ++i){
        //using "this" to pass the subject to the update method
        (*i)->Update(this);
    }
}
*/

//========================================Observer Class======================================
//Default constructor
Observer::~Observer(){
    
}

//========================================LogObserver Class======================================
//Default constructor (will open file)
LogObserver::LogObserver(){
    logFile.open("gamelog.txt", ios::app);
    cout<<"LogObserver Default Here!"<<endl;
}

//Destructor
LogObserver::~LogObserver(){
    logFile.close();
}


//Overriding the update method from Observer (will grab relevant information and update file)
void LogObserver::Update(Subject* subject){
    ILoggable* loggable = dynamic_cast<ILoggable*>(subject);
    if(loggable){
        string logEntry = loggable -> stringToLog();
        logToGameLog(logEntry);
    }
}

//implementing loToGameLog function (will write to file)
void LogObserver::logToGameLog(const string& logEntry){
    logFile << logEntry << endl;
}

Here is the .h for Orders:

#pragma once
#include <vector>
#include <string>
#include <iostream>
#include "LoggingObserver.h"



class Order : public ILoggable
{
    public:

        // default constructor
        Order();

        // constructor with order type
        Order(std::string orderType);

        // copy constructor
        Order(Order &o);

        // Overload the << operator to describe the order
        friend std::ostream & operator << (std::ostream& os, Order& order);

        // checks if an order is valid
        bool validate();

        // executes an order
        void execute();

        bool getIsExecuted();

        void setIsExecuted(bool isExecuted);

        std::string getOrderType();

        void setOrderType(std::string orderType);

        // override the assignment operator
        Order& operator=(Order& o);

        //Overriden stringToLog() method fromILoggable
        string stringToLog() override;


    private:

        std::string orderType;

        bool isExecuted;

};

// specific order classes:
class DeployOrder : public Order 
{
    public:
        // default constructor
        DeployOrder();
};
class AdvanceOrder :public  Order 
{
    public:
        // default constructor
        AdvanceOrder();
};
class BombOrder : public Order 
{
    public:
        // default constructor
        BombOrder();
};
class BlockadeOrder : public Order 
{
    public:
        // default constructor
        BlockadeOrder();
};
class AirliftOrder : public Order 
{
    public:
        // default constructor
        AirliftOrder();
};
class NegotiateOrder : public Order 
{
    public:
        // default constructor
        NegotiateOrder();
};


class OrdersList : public Subject
{

    private:
        std::vector<Order *> orders;

    public:

        // default constructor
        OrdersList();

        // copy constructor
        OrdersList(OrdersList &ol);

        // destructor
        ~OrdersList();

        std::vector<Order *> getOrders();

        Order* createOrder(std::string orderType);

        // add an order to the list
        void addOrder(Order *order);

        // change the position of an order in the order list
        void move(int listPosition1, int targerList);

        // remove an order from the order list
        void remove(int listPosition);

        // prints all the orders in the list
        void printOrdersList();
        
        // Overload the << operator to describe the order list
        friend std::ostream& operator<<(std::ostream& os, OrdersList& ordersList);
        
        // override the assignment operator
        OrdersList& operator=(OrdersList& ol);
        void Attach(Observer* o) override;
        void Detach(Observer* o) override;
        void Notify() override;
};

inline void testOrdersLists()
{
    using namespace std;
    // create an order list and add every type of oder to it
    OrdersList * ol = new OrdersList();
    ol->createOrder("Deploy");
    ol->createOrder("Advance");
    ol->createOrder("Bomb");
    ol->createOrder("Blockade");
    ol->createOrder("Airlift");
    ol->createOrder("Negotiate");

    // print all the elements in the order list
    cout << "\nInitial Order List:\n" << endl;
    cout << *ol;

    // 'execute' an order
    cout << "\n";
    ol->getOrders().front()->execute();

    // remove an order
    cout << "\n";
    ol->remove(2);

    // print all the elements in the new order list
    cout << "\nRemoved Order 2 from list:\n" << endl;
    cout << *ol;

    // move an order
    cout << "\n";
    ol->move(1,2);

    // print all the elements in the new order list
    cout << "\nChanged the first order to be the seconds order:\n" << endl;
    cout << *ol;

}

And here is the .cpp for orders:

#include <iostream>
#include <vector>
#include <string>
#include "Orders.h"
#include "LoggingObserver.h"


// list<Order *> orders = ol->getOrders(); // Make a copy of the list to avoid iterator issues

using namespace std;

// default order constructors:

// generic order
Order::Order(){
    setOrderType("Generic");
    setIsExecuted(false);
}

// order with type
Order::Order(string orderType){
    this->setOrderType(orderType);
    setIsExecuted(false);
}

//Overriden stringToLog() method fromILoggable
string Order::stringToLog() {
    string log = "Observing Issueing Orders Phase information is: \n Orders: " + orderType;
    return log;
}

// deploy order
DeployOrder::DeployOrder()
: Order("Deploy") {}

// advance order
AdvanceOrder::AdvanceOrder()
: Order("Advance") {}

// bomb order
BombOrder::BombOrder()
: Order("Bomb") {}

// blockade order
BlockadeOrder::BlockadeOrder()
: Order("Blockade") {}

// airlift order
AirliftOrder::AirliftOrder()
: Order("Airlift") {}

// negotiate order
NegotiateOrder::NegotiateOrder()
: Order("Negotiate") {}


// copy constructor
Order::Order(Order &o)
{
    setOrderType(o.getOrderType());
}

string Order::getOrderType() { return orderType; }

void Order::setOrderType(string type) { orderType = type; }

bool Order::getIsExecuted() { return isExecuted; } 

void Order::setIsExecuted(bool isExecuted) { this->isExecuted = isExecuted; }


bool Order::validate()
{
    return true;
}

void Order::execute()
{
    if(validate())
    {
        cout << "Executing " << this->orderType << std::endl;
        setIsExecuted(true);
    }
}

// stream operator order
std::ostream & operator << (std::ostream& os, Order & order)
{
    os << "This is a " << order.getOrderType() << " order. ";

    if(order.getIsExecuted())
    {
        os << "Order was executed";
    }
    os << std::endl;

    return os;
}

// assignment operater order
Order& Order::operator=(Order& o)
{ 
    o.setOrderType(getOrderType());
    o.setIsExecuted(getIsExecuted());
    return *this;
} 

// Order list:

// default constructor
OrdersList::OrdersList(){
    cout<<"OrderList Constructer here!"<<endl;
}

// destructor
OrdersList::~OrdersList()
{
    for (Order *order : orders) {
        delete order;
    }
    orders.clear();
}

// copy constructor
OrdersList::OrdersList(OrdersList &ol)
{
    this->orders = ol.getOrders();
}


// stream operator order list
ostream& operator<<(ostream& os, OrdersList & ol)
{
    int i = 0;
    for (Order *order : ol.getOrders()) 
    {
        os << ++i << ": ";
        os << *order ;
    }
    return os;
}

vector<Order *> OrdersList::getOrders()
{
   return this->orders;
}

Order* OrdersList::createOrder(std::string orderType)
{
    Order *newOrder;
    if(orderType == "Deploy")
    {
        newOrder = new DeployOrder();
    }

    else if(orderType == "Advance")
    {
        newOrder = new AdvanceOrder();
    }
    else if(orderType == "Bomb")
    {
        newOrder = new BombOrder();
    }
    else if(orderType == "Blockade")
    {
        newOrder = new BlockadeOrder();
    }
    else if(orderType == "Airlift")
    {
        newOrder = new AirliftOrder();
    }
    else if(orderType == "Negotiate")
    {
        newOrder = new NegotiateOrder();
    }
    else
    {
        newOrder = new Order();
    }
    this->addOrder(newOrder);
    return newOrder;
}

void OrdersList::addOrder(Order *order)
{
    orders.push_back(order);
    Notify();
}

void OrdersList::move(int initialListPosition, int targetListPosition)
{
    // verifiy that the index positions are valid
    int listSize = orders.size();
    if(initialListPosition > listSize || initialListPosition < 1 || targetListPosition > listSize || targetListPosition < 1)
    {
        cout << "Invalid move" << std::endl;
    }
    else
    {
        // remove the order
        vector<Order *>::iterator itr1 = orders.begin();
        advance(itr1,initialListPosition-1);
        Order * o = *itr1; // save a pointer to the order before removing it
        orders.erase(itr1);

        // add it back in the new index
        vector<Order*>::iterator itr2 = orders.begin();
        advance(itr2,targetListPosition-1);
        orders.insert(itr2, o);

        cout << "Order moved" << std::endl;
    }
}


void OrdersList::remove(int listPosition)
{
    
    vector<Order *>::iterator itr = orders.begin();
    advance(itr,listPosition-1);
    orders.erase(itr);

    cout << "Order removed" << std::endl;
}

void OrdersList::printOrdersList()
{
    int i = 0;
    for (Order *order : orders) 
    {
        cout << ++i << ": ";
        cout << *order ;
    }
}

// assignment operater order
OrdersList& OrdersList::operator=(OrdersList& ol)
{ 
    for (Order* order : ol.getOrders()) {
        // Assuming that Order has a copy constructor
        orders.push_back(new Order(*order));
    }
    return *this;
} 

void OrdersList::Attach(Observer* o){
    observers->push_back(o);
    cout << "im attaching"<<endl;
}

//Implementation of Remove method (removes an observer from the observers list)
void OrdersList::Detach(Observer* o){
    observers->remove(o);
}

//Implementation of the Notify method (will call on the observers update method)
void OrdersList::Notify(){
    list<Observer*>::iterator i = observers->begin();
    for(;i != observers->end(); ++i){
        //using "this" to pass the subject to the update method
        cout << "im notifying"<<endl;
        (*i)->Update(this);
    }
}