Skip to content

Instantly share code, notes, and snippets.

View sadache's full-sized avatar

Sadek Drobi sadache

View GitHub Profile

At last an article that analyses the situation beyond the hype, this is how we can grow better solutions for the future, by constructive critic.

Headless CMS can’t be the goal on its own. There are plenty of problems to be solved in content management to increase flexibility and agility. Being API-based is, however, a solid corner stone, a foundation for the future that allows unlimited extensibility.

Pretty much like when the IPhone was announced, critics have targeted its simplicity and lack of features (premature virtual keyboard and lack of a physical one, its battery consumption, its fragility). Look at the market now, completely transformed and big actors like Nokia are now unheard of!

We’re going into the same transformation in the CMS world. Back when we announced our product, we’ve said that there are plenty of challenges to be addressed, I am glad this article mentioned quite a few!

None of these shortcomings are actually inherent to the API-based foundation. They just didn’t get enough attentio

{
"Header" : {
"title" : {
"type" : "StructuredText",
"config" : {
"single" : "heading1"
}
},
"subtitle" : {
"type" : "StructuredText",
@sadache
sadache / gist:d357ced8f6c942bca81a
Last active August 29, 2015 14:02
Faster with much less memory consumption JSON object reader
def objectReader[T1,T2,T3,T4,R](t1: String, t2: String, t3: String, t4: String)(f: (T1,T2,T3,T4) => R)(implicit readsT1:Reads[T1], readsT2:Reads[T2], readsT3:Reads[T3], readsT4:Reads[T4]): Reads[R] = {
def orElse[A](a:A, default: =>A) = if(a!=null) a else default
Reads[R]{
case JsObject(fields) =>
var t1V:JsResult[T1] = null.asInstanceOf[JsResult[T1]]
var t2V:JsResult[T2] = null.asInstanceOf[JsResult[T2]]
@sadache
sadache / gist:8804038
Last active August 29, 2015 13:56
A naive, potentially buggy and largely improvable implementation of Enumerator[Array[Byte]] to InputStream
import java.io.InputStream
import play.api.libs.iteratee.{ Enumerator, Iteratee }
import scala.concurrent.Promise
import scala.concurrent.ExecutionContext.Implicits.global
import scala.util.{ Success, Failure }
import java.util.concurrent.ArrayBlockingQueue
import java.util.concurrent.atomic.AtomicInteger
def toInputStream(chunks: Enumerator[Array[Byte]], bufferSize: Int): InputStream = new InputStream {
var api = Api.get("https://lesbonneschoses.prismic.io/api")
// Find all macarons
var products = api.then(function(api) {
return api.forms['products']
.query('[[:d = at(document.tags, "Macaron")]]')
.ref(api.master)
.submit()
})
package controllers
import scala.concurrent._
import ExecutionContext.Implicits.global
import play.api.libs.iteratee._
import play.api._
import play.api.mvc._
import play.api.libs._
@sadache
sadache / Application.scala
Last active December 16, 2015 01:09
Fixes several leaking Enumerators and features buffer Enumeratee which buffers when socket is not ready for writing
ackage controllers
import play.api._
import play.api.mvc._
import play.api.libs.iteratee._
import play.api.libs.EventSource
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.{Future, Promise}
// Solves memory leaks
@sadache
sadache / gist:4714280
Last active July 14, 2022 15:09
Playframework: Async, Reactive, Threads, Futures, ExecutionContexts

Asynchronicity is the price to pay, you better know what you're paying for...

Let's share some vocabulary first:

Thread: The primitive responsible of executing code on the processor, you can give an existing (or a new) Thread some code, and it will execute it. Normally you can have a few hundreds on a JVM, arguments that you can tweak your way out to thousands. Worth noting that multitasking is achieved when using multiple Threads. Multiple Threads can exist for a single processor in which case multitasking happens when this processor switches between threads, called context switching, which will give the impression of things happenning in parallel. An example of a direct, and probably naive, use of a new Thread in Java:

public class MyRunnable implements Runnable {
  public void run(){
 System.out.println("MyRunnable running");
@sadache
sadache / 1-post.md
Created September 5, 2012 22:14
Applicatives are too restrictive, breaking Applicatives and introducing Functional Builders

This post aims to document a practical design implementation we came up with when designing some APIs in Scala. Of course the concept is not Scala specific and applies to other functional languages.

If you don't want to go into the full introduction, this post talks about how Applicatives are too restrictive and breaking them into two independent components can be interesting for Contravariant and Invariant Functors. Jump to implementation attached.

We are taking JSON serialization/deserialization as a motivating example.

JsValue is the name of the type that represents the JSON AST. What we need is to be able to read a JsValue and produce an A:

trait Reads[A]{
@sadache
sadache / gist:3382059
Created August 17, 2012 19:58 — forked from mandubian/gist:3377514
Play2 new plugin: File NonBlocking/Async API - Copying a file
"copy file" in {
val fileGenerator = Enumerator.repeat(new java.util.Date.getTime.toString + "\n").through(Enumeratee.take(1000))
//val fileGenerator = Enumerator.repeat(new java.util.Date.getTime.toString + "\n") &>> Enumeratee.take(1000)
val f = FileChannel("/tmp/testwrite.txt").delete.writing.create
val f2 = FileChannel("/tmp/testwrite2.txt").delete.writing.create
fileGenerator // generates data
.through(RichEnumeratee.binarize()) // binarizes data to write into File