Thursday, November 10, 2016

Today we take a break to discuss stateful APIs. With the move towards REST Framework most of the APIs are necessarily and correctly stateless. However, once in a while we do come across use cases where the APIs have to be stateful. Take for instance a native os command. Within the APIs, we can invoke a native system command and return the output each time we encounter a command. Since all the commands issued are maintained in the .bash_history, we don't always require to maintain state. and can even replay the commands issued assuming they are idempotent. But if we open a python console and start issuing python statements, we no longer have that state unless we redirect the input and output via the pipes to the API and even so there is no stashing unless the APIs keep track of it separately.
Enter request.session.session_key and we now solve this for every session initiated by the user by attaching the state to the session. Since the state can be persisted, all we have to do is name the state with the session key so we can tell apart the sessions. Still this is mostly a front-end call and the APIs remain stateless. Many UI framework support this model by facilitating the notion of sessions.
So the question really is should the statefulness be pushed down to the API ?
Pautasso et al. classify the application integration style  as shared database, remote procedure call, message bus and File Transfer.

#codingexercise
Problem: Given a sequence of words, print all anagrams together. 

Sort the letters within a word
Sort the words in the sequence
This brings the anagram groupings
Since each anagram keeps track of its index in the sequence we can find the corresponding words and their groupings.
Void PrintAllAnagrams(List<string> words) 
{ 
Var items = new List<Tuple<string, int>>(); 
Words.enumerate((x,i) => items.Add(new Tuple<string, int>(x, i))); 
Items.forEach(x => sort(x)); 
Items.sort(new TupleSorter()); 
Items.ForEach(x => console.writeLine("{0} at index {1}", words[x.second], x.second); 
  
} 
Or we could simply cluster them based on anagram similarity. This clustering has to be hierarchical since we don’t know the number of anagrams and the threshold has to be zero because we are looking for exact similarity and anything else is not. 
  
Void PrintAllAnagramsByClustering(List<string> words) 
{ 
Var items = new List<Tuple<List<string>, int>>(); 
Words.enumerate((x,i) => items.Add(new Tuple<List<string>, int>(new List<string>(x),-1))); // all items have label -1 at start 
Bool over = false; 
While (!over) 
{ 
Var newCluster = new Tuple<List<string>, int>(); 
For ( int I =0; I < items.length; i++) 
    For (int j =i+1; j < items.Length; j++) 
    { 
   If (i != j && distance(items[i], items[j]) == 0) && items[I].second != items[j].second){ 
           match = true; 
           var merged = merge(items[i], items[j], i); 
           If (newCluster.Contains(merged) == false) 
               NewCluster.Add(merge); 
    } 
Foreach (var item in items) 
       If newcluster.contains(item) 
           Items.Remove(item); 
      Else 
           Item.second = -1; 
If (newCluster.empty() == false) 
     Item.Append(newCluster);  
  If (newCluster.empty()){ 
        Console.WriteLine(newCluster.ToString()); 
         over = true; 
     } 
} 
} 
  
We could also use a hashing function that computes the sum of the ascii values of the letters in the words.
  

No comments:

Post a Comment