mercredi 22 janvier 2020

In The Observer Design Pattern How Is The Subject Class Stored?

I've been reading up on the Observer Design Pattern.

Take the below code from the following article: https://sourcemaking.com/design_patterns/observer/python/1

I understand how the code works and how the two classes, subject and observer, interrelate. What I can't quite get my head round is how this would all work in reality.

In the real world examples of the observer pattern I have read about, the interaction between the subject and observer tends to be open ended. For example, if you subscribe to a question on Quora and get notified of answers via email, theoretically, you could receive updates indefinitely.

How then if the code below was applied to a real world scenario (like Quora) do the classes persist? Are the classes and their states stored somewhere on the server?

import abc


class Subject:
    """
    Know its observers. Any number of Observer objects may observe a
    subject.
    Send a notification to its observers when its state changes.
    """

    def __init__(self):
        self._observers = set()
        self._subject_state = None

    def attach(self, observer):
        observer._subject = self
        self._observers.add(observer)

    def detach(self, observer):
        observer._subject = None
        self._observers.discard(observer)

    def _notify(self):
        for observer in self._observers:
            observer.update(self._subject_state)

    @property
    def subject_state(self):
        return self._subject_state

    @subject_state.setter
    def subject_state(self, arg):
        self._subject_state = arg
        self._notify()


class Observer(metaclass=abc.ABCMeta):
    """
    Define an updating interface for objects that should be notified of
    changes in a subject.
    """

    def __init__(self):
        self._subject = None
        self._observer_state = None

    @abc.abstractmethod
    def update(self, arg):
        pass


class ConcreteObserver(Observer):
    """
    Implement the Observer updating interface to keep its state
    consistent with the subject's.
    Store state that should stay consistent with the subject's.
    """

    def update(self, arg):
        self._observer_state = arg
        # ...


def main():
    subject = Subject()
    concrete_observer = ConcreteObserver()
    subject.attach(concrete_observer)
    subject.subject_state = 123


if __name__ == "__main__":
    main()



Is it right to use query to database in my Business Logic Layer?

I have a music database. Suppose I need to show the user recommended songs. This will require many different SQL requests to the database. But since the recommendation search algorithm will contain business logic, it will be wrong if I implement it in Data Access Layer.

So what better way to do it? Put an algorithm in Business Logic Layer and implement it using methods from Data Access Layer? In my opinion it will be a little inconvenient.

Sorry for the possibly stupid question, I'm just trying to understand all these layers.

how to avoid switch statement?

I'm trying to learn client/server in java until now i got the basics. here how to accept and serve out many clients

public class Server {
    ServerSocket serverSocket;

    public void startServer() throws IOException {
        serverSocket= new ServerSocket(2000);
        while (true){
            Socket s= serverSocket.accept();
            new ClientRequestUploadFile(s).start(); //here is the first option.
        }
    }
}

Now suppose i have too many type of options the client can request. the code will be as follow :

public void startServer() throws IOException {
        serverSocket= new ServerSocket(2000);
        while (true){
            Socket s= serverSocket.accept();
            DataInputStream clientStream= new DataInputStream(s.getInputStream());
            String requestName=clientStream.readUTF();
            switch (requestName){
                case "ClientRequestUploadFile": new ClientRequestUploadFileHandler(s).start();break;
                case "clientRequestCalculator": new clientRequestCalculatorHandler(s).start();break;
                case "clientRequestDownloadFile": new clientRequestDownloadFileHandler(s).start();break;
            }
        }
    }

if there 100 of options,is there any way to avoid switch statement(design-patterns maybe)? keep in mind that may occur new option in the future.

Synchronizing data between Django and different data sources

I have a Django 2.2 app with using only its ORM features (no admin, views, URL routing) in which I have the two following models (in reality it's more but it's just for the sake of giving a straightforward example):

from django.db import models

class Person(models.Model):
    name = models.CharField(max_length=100)
    age = models.IntegerField()
    job = models.ForeignKey('myapp.Job')

class Job(models.Model):
    title = models.TextField()
    description = models.TextField()
    entry_date = models.DateField()

Now, I would like to be able to periodically synchronize the objects stored in my Django app with one or more external date sources (actually its concerns only a MySQL db and a REST API but it's likely I'm going to have to plug-in new data sources in some time).

The "direction" of the synchronization depends on the data source used, with one I'm only pulling data into my Django app, with the other I'm exporting data from my Django app, creating new objects when necessary, doing the updates, deletes, etc., and my with another data source I'm doing sync both ways.

All the external data sources have a different data layout and in order to import/export some fields to/from my app, I'll have to do some work ; e.g. on a data source, the value corresponding to my entry_date field on the Job model is stored in a funky timestamp and thus, it obligates me to do a conversion on it before I can use it at all.

However, I'm really struggling to figure how I could implement this in my Django app.

The first thing I've tried to design is, implementing CRUD operations for all my data sources using class abstraction but I obviously need a mechanism to have bindings between the fields of my Django app and the all different data layout of my sources. And yet, I'm seeking for maximal abstraction here, keeping all the data treatment and logic separated from the CRUD operations.

Pythonic way to pass arguments

The main() function is in model_executor.py. The executor fetches from parse_modelscore and in execute_model function calls eval_expression with arguments model_data and json_data. The evaluation Starts from the model eval_expression which has three different type of evaluation: eval_number_expression, eval_string_expression, eval_boolean_expression. The expression are nested expression which could contain many different types of expression inside. So during evaluation of arithmetic expression it needs to call back the eval_number_expression which may evaluate attribute _lookup. And eval_attribute_lookup is the only function that requires model_in which I’m using by declaring global variable. Is there any other way to pass model_in without adding as an arguments to every functions. There are many functions which calls eval_number_expression/string/boolean.

eval_model_def.py

def eval_literal_number(exp, definitions=None, defn_table=None):
      if isinstance(exp, numbers.Number):
        return exp
      return None

 def eval_tree(exp, ...):
     return eval_val
 def eval_case(exp, ...):
     return eval_val

def eval_arithmetic(exp,definitions=None, defn_table=None):
    if not isinstance(exp, list):
        return None
    operands = []
    for idx,item in enumerate(exp[1:], 1):
        print("item", item)
        result = eval_number_expression(item, definitions, defn_table)
        if result is None:
            return None
        operands.append(result)
    op = exp[0]
    if op =="+":
       ret =do mathematical operation for all operators    
    else:
      return None
    return ret

def eval_attribute_lookup(a, exp,definitions=None, defn_table=None):
    if isinstance(exp, list) and len(exp) == 2:
        if exp[0] == "attribute_lookup":
            if isinstance ( exp[1], dict):
                name = exp[1]["name"]
                source = exp[1]["source"]
                result = a[name]
                try:
                    result = int(result)
                except ValueError:
                    result = float(result)
                return result
    return None

def eval_number_expression(exp,definitions=None, defn_table= None):
    operations = [eval_literal_number, eval_arithmetic,eval_numeric_functions,eval_definition_lookup, eval_attribute_lookup,eval_tree, eval_case, eval_linear]
    for o in operations:
        if o ==eval_attribute_lookup:
           o = partial(eval_attribute_lookup, model_in)
        result = o(exp,i, definitions, defn_table)
        if result is not None:
            return result
    return None

def eval_expression(exp,input_at = None,definitions=None,defn_table=None):
    print("-" *i +"eval_expression")
    global model_in

    model_in = input_at

    operations = [eval_number_expression,eval_string_expression, eval_boolean_expression]
    for o in operations:
        result = o(exp, i,definitions, defn_table)
        if result is not None:
           return result
    return None

 model_executor.py
 import parse_modelscore as parse
 import eval_model_def as eval

 def prepare_data(a):
   get data from parse

 def get_json_exp(a):
      return exp

 def execute_model(model_data, json_data):
     data = prepare_data(model_data)
     exp  = get_json_exp(json_data) 
     value = eval.eval_expression(exp, data)

json example

"definitions": [
    {
      "name": "raw_score",
      "type": "number",
      "value": ["+", 1, 2, 3, ["*", 2,["definition_lookup", "add_thing"]]]
    },
    { "name": "add_thing",
      "type": "number",
      "value": ["+", 5, ["definition_lookup", "my_tree"]]
    },
    {
      "name": "my_tree",
      "type": "number",
      "value": ["case",
                 ["attribute_lookup", {"name":"aggs903", "source":"EADS14"}],
                 {
                  "when":[
                    {"op":"=", "comparand":-2.0, "value":0.0},
                    {"op":"=", "comparand": -1.0, "value":0.0},
                    {"op":"<", "comparand":242.0, "value":2.610552},
                    {"op": ">", "comparand":1156.0, "value":2.119683}
                  ],
                  "otherwise":-0.703241
                 }
                ]
    }
  ]

Active Object design pattern in physically seperated distributed system

I have a question regarding the Active Object design pattern. It decouples method execution from method invocation. So far so good and in the POSA book of Douglas Schmidt it is presented as concurrency and multi-thread pattern. But the Client and the Active Object is running on the same processor and share same memory.

Now I would like to seperate Client and Active Object, so that they are running on different machines, no sharing of memory. This could a multicomputing system or a web application. How can I achieve that?

I tought, I could maybe replace the Proxy of the Active with a Broker (POSA book) or Gateway (Martin Fowler) but to be honest, I can not tell which approach is the better one or if they are even correct.

Who has an idea for that? Thank you!

Rabbit mq message broker in multi-tenants web application

I need to move a single-tenant web application to a multi-tenant (about 100 tenants) web application. Tenants are going to share the same application but each tenant is going to have its own database (database for tenants) I have already planned to move my in-process application cache to a shared distribuited cache identifing cache items by adding a prefix (the tenant-id) to the cache iteme keys (prepended-tenant pattern).

Application also rely on RabitMQ to implement async processes. Actualy I don't have many queues, just a dozen and few exchanges but i suppose the number of queue and exchange is going to increase in the future.

Now Im confused about the best architectural pattern for queues when moving toward a multi-tenant architecture.

Choices:

1) Multiple virtual host (one per tenant) with same topology replicated per virtual host

2) Single virtual hoost with same queues, exhanges, ecc shared among tenants.

The first choice seems to be more complicated to manage as I shoud keep syncronized the topology for every virtual host (suppose 100 tenants means 100 vhost) The second choice seams the easier one, I only need to pass in the context of every messages sent to queues the tenant-identifier so the consumer knows who is the owner of the message and what to do with it.

I would know some opinions mainly with regards to the second choice as it seems to me more affordable.