SlideShare une entreprise Scribd logo
1  sur  109
Jarek Ratajski
@jarek000000
DROP DB
Jarek Ratajski
Developer, wizard, anarchitectDeveloper, wizard, anarchitect
Lives in LuzernLives in Luzern
Works in CSS InsuranceWorks in CSS Insurance
C64, 6502, 68000, 8086, C++, Java, JEE, Scala, Akka, JS,C64, 6502, 68000, 8086, C++, Java, JEE, Scala, Akka, JS,
ScalaJS....ScalaJS....
jratajski@gmail.comjratajski@gmail.com @jarek000000@jarek000000
Multiversum
MULTIVERSUMMULTIVERSUM
I know only one history
Who cares?
Real life case
Galakpizza
10 000 Planets 3 Variants
3 Sizes
HAWAII
MARGHERITTA
VEGETARIAN
MEDIUM
LARGE
XL
Domain summary
MARGHERITTA MEDIUM
HAWAII LARGE
HAWAII LARGE
VEGERARIAN LARGE
HAWAII XL
MARGHERITTA XL
HAWAII LARGE
HAWAII LARGE
HAWAII LARGE
HAWAII LARGE
33
33
11
11
Delivery model
10 000 Pizzas / s
I want to look at number
of queued orders 10000 times / s
My wife also!
Requirements
Alien development
(in 2 „parallel“ universes)
Normal universe Other universe
++
In Normal universe
https://github.com/airomem/galakpizza/tree/master/galakpizza_n
Normal domain
public class Order implements Serializable {
private static final long serialVersionUID = 1L;
public final long id;
public final String planet;
public final Variant variant;
public final Size size;
public Order(long id, String planet, Variant variant, Size size) {
this.id = id;
this.planet = planet;
this.size = size;
this.variant = variant;
}
}
Normal domain 2
public enum Size {
MEDIUM,
LARGE,
XL
}
public enum Variant {
HAWAII,
MARGHERITA,
VEGETARIAN
}
Normal Service
public interface GalakPizzaOrders {
long placeOrder(String planet, Variant variant, Size size);
}
Normal Service
public interface GalakPizzaOrders {
long placeOrder(String planet, Variant variant, Size size);
}
public interface GalakPizzaDelivery {
List<Order> takeOrdersFromBestPlanet();
long countStandingOrders();
}
Normal Service
public interface GalakPizzaOrders {
long placeOrder(String planet, Variant variant, Size size);
}
public interface GalakPizzaDelivery {
List<Order> takeOrdersFromBestPlanet();
long countStandingOrders();
}
public interface GalakPizzaService extends GalakPizzaDelivery,
GalakPizzaOrders{
}
Normal service implementation...
public class GalakPizzaCore implements GalakPizzaService, Serializable,
Storable<GalakPizzaCore> {
public long placeOrder(String planet, Variant variant, Size size) {
...
}
public List<Order> takeOrdersFromBestPlanet() {
...
}
public long countStandingOrders() {
...
}
}
Normal service implementation...
public class GalakPizzaCore implements GalakPizzaService, Serializable,
Storable<GalakPizzaCore> {
private finalprivate final Map<String, List<Order>>Map<String, List<Order>> ordersorders == newnew HashMap<>();HashMap<>();
public long placeOrder(String planet, Variant variant, Size size) {
...
}
public List<Order> takeOrdersFromBestPlanet() {
...
}
public long countStandingOrders() {
...
}
}
Normal service implementation...
public class GalakPizzaCore implements GalakPizzaService, Serializable,
Storable<GalakPizzaCore> {
private finalprivate final Map<String, PlanetOrders>Map<String, PlanetOrders> ordersorders == newnew HashMap<>();HashMap<>();
public long placeOrder(String planet, Variant variant, Size size) {
...
}
public List<Order> takeOrdersFromBestPlanet() {
...
}
public long countStandingOrders() {
...
}
}
PlanetOrders - helper
class PlanetOrders implements Serializable {
final String name;
private List<Order> orders = new ArrayList<>();
public PlanetOrders(String name) {
this.name = name;
}
...
}
PlanetOrders - helper
class PlanetOrders implements Serializable {
final String name;
private List<Order> orders = new ArrayList<>();
public PlanetOrders(String name) {
this.name = name;
}
void assignOrder(final Order order) {
this.orders.add(order);
}
...
}
PlanetOrders - helper
class PlanetOrders implements Serializable {
final String name;
private List<Order> orders = new ArrayList<>();
public PlanetOrders(String name) {
this.name = name;
}
void assignOrder(final Order order) {
this.orders.add(order);
}
public boolean isEmpty() {
return this.orders.isEmpty();
}
...
}
Normal place order
public class GalakPizzaCore implements GalakPizzaService, Serializable,
Storable<GalakPizzaCore> {
private final Map<String, PlanetOrders> orders = new HashMap<>();
private long orderSequence = 1;
public long placeOrder(String planet, Variant variant, Size size) {
final long id = orderSequence++;
final Order order = new Order(id, planet, variant, size);
assignOrderToPlanet(order);
return id;
}
Normal place order
public class GalakPizzaCore implements GalakPizzaService, Serializable,
Storable<GalakPizzaCore> {
private final Map<String, PlanetOrders> orders = new HashMap<>();
private long orderSequence = 1;
public long placeOrder(String planet, Variant variant, Size size) {
final long id = orderSequence++;
final Order order = new Order(id, planet, variant, size);
assignOrderToPlanet(order);
return id;
}
private void assignOrderToPlanet(Order order) {
final PlanetOrders po = orders.computeIfAbsent(order.planet,
planetName -> new PlanetOrders(planetName));
po.assignOrder(order);
...
Normal place order
public class GalakPizzaCore implements GalakPizzaService, Serializable,
Storable<GalakPizzaCore> {
private final Map<String, PlanetOrders> orders = new HashMap<>();
private long orderSequence = 1;
private AtomicLong ordersTotal = new AtomicLong(0);
public long placeOrder(String planet, Variant variant, Size size) {
final long id = orderSequence++;
final Order order = new Order(id, planet, variant, size);
assignOrderToPlanet(order);
ordersTotal.incrementAndGet();
return id;
}
private void assignOrderToPlanet(Order order) {
final PlanetOrders po = orders.computeIfAbsent(order.planet,
planetName -> new PlanetOrders(planetName));
po.assignOrder(order);
...
Normal place order revisited
public class GalakPizzaCore { ...
private final Map<String, PlanetOrders> orders = new HashMap<>();
private PriorityQueue<PlanetOrders> bestPlanets = new PriorityQueue<>(256);
private long orderSequence = 1;
private AtomicLong ordersTotal = new AtomicLong(0);
public long placeOrder(String planet, Variant variant, Size size) {
final long id = orderSequence++;
final Order order = new Order(id, planet, variant, size);
assignOrderToPlanet(order);
ordersTotal.incrementAndGet();
return id;
}
private void assignOrderToPlanet(Order order) {
final PlanetOrders po = orders.computeIfAbsent(order.planet,
planetName -> new PlanetOrders(planetName));
po.assignOrder(order);
this.bestPlanets.offer(po);
}
Normal place order revisited
public class GalakPizzaCore { ...
private final Map<String, PlanetOrders> orders = new HashMap<>();
private PriorityQueue<PlanetOrders> bestPlanets = new PriorityQueue<>(256);
private long orderSequence = 1;
private AtomicLong ordersTotal = new AtomicLong(0);
public long placeOrder(String planet, Variant variant, Size size) {
final long id = orderSequence++;
final Order order = new Order(id, planet, variant, size);
assignOrderToPlanet(order);
ordersTotal.incrementAndGet();
return id;
}
private void assignOrderToPlanet(Order order) {
final PlanetOrders po = orders.computeIfAbsent(order.planet,
planetName -> new PlanetOrders(planetName));
po.assignOrder(order);
this.bestPlanets.offer(po); BAD BAD BAD BAD
}
Normal place order revisited
public class GalakPizzaCore { ...
private final Map<String, PlanetOrders> orders = new HashMap<>();
private PriorityQueue<PlanetOrders.Wrapper> bestPlanets = new PriorityQueue<>(256);
private long orderSequence = 1;
private AtomicLong ordersTotal = new AtomicLong(0);
public long placeOrder(String planet, Variant variant, Size size) {
final long id = orderSequence++;
final Order order = new Order(id, planet, variant, size);
assignOrderToPlanet(order);
ordersTotal.incrementAndGet();
return id;
}
private void assignOrderToPlanet(Order order) {
final PlanetOrders po = orders.computeIfAbsent(order.planet,
planetName -> new PlanetOrders(planetName));
po.assignOrder(order);
this.bestPlanets.offer(new PlanetOrders.Wrapper(po));
}
Wrapper... yeah
public static class Wrapper implements Comparable<Wrapper>,Serializable{
final PlanetOrders porders;
final int size; //just keep it final
public Wrapper(PlanetOrders porders) {
this.porders = porders;
this.size = porders.orders.size();
}
@Override
public int compareTo(final Wrapper other) {
return other.size - this.size;
}
}
PlanetOrders – take orders
class PlanetOrders implements Serializable {
final String name;
private List<Order> orders = new ArrayList<>();
List<Order> takeOrders() {
final List<Order> result = this.orders;
this.orders = new ArrayList<>();
return result;
}
public boolean isEmpty() {
return this.orders.isEmpty();
}
}
PlanetOrders – take orders
class PlanetOrders implements Serializable {
final String name;
private List<Order> orders = new ArrayList<>();
List<Order> takeOrders() {
final List<Order> result = this.orders;
this.orders = new ArrayList<>(); //yes we MUTATE!
return result;
}
public boolean isEmpty() {
return this.orders.isEmpty();
}
}
CYPS 2(2) ZYPS 1(1)
CYPS 2(2) ZYPS (1)ZYPS 2(2)
+ Order 1 Hawaii XL to ZYPS
CYPS 2(2) ZYPS 1(0)
Take Orders
ZYPS 1(0)
Take Orders
IsEmpty => ignore
Normal take orderspublic class GalakPizzaCore implements GalakPizzaService, Serializable,
Storable<GalakPizzaCore> {
privateprivate PriorityQueue<PlanetOrders.Wrapper>PriorityQueue<PlanetOrders.Wrapper> bestPlanetsbestPlanets == newnew
PriorityQueue<>(PriorityQueue<>(256256););
private AtomicLong ordersTotal = new AtomicLong(0);
public List<Order> takeOrdersFromBestPlanet() {
final Optional<PlanetOrders> planetOpt = takeBestPlanet();
....
}
private Optional<PlanetOrders> takeBestPlanet() {
PlanetOrders.Wrapper planet = this.bestPlanets.poll();
while (planet != null && planet.porders.isEmpty()) {
planet = this.bestPlanets.poll();
}
return Optional.ofNullable(planet).map(p->p.porders);
}
Normal take orderspublic class GalakPizzaCore implements GalakPizzaService, Serializable,
Storable<GalakPizzaCore> {
privateprivate PriorityQueue<PlanetOrders.Wrapper>PriorityQueue<PlanetOrders.Wrapper> bestPlanetsbestPlanets == newnew
PriorityQueue<>(PriorityQueue<>(256256););
private AtomicLong ordersTotal = new AtomicLong(0);
public List<Order> takeOrdersFromBestPlanet() {
final Optional<PlanetOrders> planetOpt = takeBestPlanet();
if (planetOpt.isPresent()) {
final PlanetOrders planet = planetOpt.get();
List<Order> orders = planet.takeOrders();
return orders;
}
return Collections.EMPTY_LIST;
}
private Optional<PlanetOrders> takeBestPlanet() {
PlanetOrders.Wrapper planet = this.bestPlanets.poll();
while (planet != null && planet.porders.isEmpty()) {
planet = this.bestPlanets.poll();
}
return Optional.ofNullable(planet).map(p->p.porders);
}
Normal take orderspublic class GalakPizzaCore implements GalakPizzaService, Serializable,
Storable<GalakPizzaCore> {
privateprivate PriorityQueue<PlanetOrders.Wrapper>PriorityQueue<PlanetOrders.Wrapper> bestPlanetsbestPlanets == newnew
PriorityQueue<>(PriorityQueue<>(256256););
private AtomicLong ordersTotal = new AtomicLong(0);
public List<Order> takeOrdersFromBestPlanet() {
final Optional<PlanetOrders> planetOpt = takeBestPlanet();
if (planetOpt.isPresent()) {
final PlanetOrders planet = planetOpt.get();
List<Order> orders = planet.takeOrders();
ordersTotal.addAndGet(-orders.size());
return orders;
}
return Collections.EMPTY_LIST;
}
private Optional<PlanetOrders> takeBestPlanet() {
PlanetOrders.Wrapper planet = this.bestPlanets.poll();
while (planet != null && planet.porders.isEmpty()) {
planet = this.bestPlanets.poll();
}
return Optional.ofNullable(planet).map(p->p.porders);
}
Normal count orders
private AtomicLong ordersTotal = new AtomicLong(0);
public long countStandingOrders() {
return this.ordersTotal.get();
}
We have service - but do we deal with?
●
Concurrency
●
Persistence
Normal - Alien service wrapper
public class GalakPizza implements GalakPizzaService {
final PersistenceController<GalakPizzaCore,GalakPizzaCore> controller;
public GalakPizza() {
controller = PrevaylerBuilder.newBuilder()
.withinUserFolder("pizza")
.useSupplier( () -> new GalakPizzaCore())
.disableRoyalFoodTester()
.build();
}
public long placeOrder(final String planet, final Variant variant, final Size size) {
return controller.executeAndQuery( core -> core.placeOrder(planet,variant,size));
}
public List<Order> takeOrdersFromBestPlanet() {
return controller.executeAndQuery( core ->core.takeOrdersFromBestPlanet());
}
public long countStandingOrders() {
return controller.query( c->c.countStandingOrders());
}
...
}
Done!
In alternative universe
https://github.com/airomem/galakpizza/tree/master/galakpizza_h
Other Domain
@Entity
@Table(name="T_ORDER")
@NamedQueries( {
@NamedQuery(name = "select best planet", query = "SELECT o.planet, count(o) FROM Order o " +
" GROUP BY o.planet ORDER BY count(o) desc"),
@NamedQuery(name = "select orders", query = "SELECT o FROM Order o WHERE o.planet = :planet"),
@NamedQuery(name = "count orders", query = "SELECT count(o) FROM Order o ")
})
public class Order {
@Id
@GeneratedValue(generator="increment")
@GenericGenerator(name="increment", strategy = "increment")
final long id;
public final String planet;
public final Variant variant;
public final Size size;
protected Order() {
this("this is strange...", null, null);
}
public Order(String planet, Variant variant, Size size) {
this.planet = planet;
this.variant = variant;
this.size = size;
id = 0;
}
public long getId() {
return id;
}
}
Other domain (same as above)
public enum Size {
MEDIUM,
LARGE,
XL
}
public enum Variant {
HAWAII,
MARGHERITA,
VEGETARIAN
}
It is in TABLE
so it exists
Other service (same)
public interface GalakPizzaOrders {
long placeOrder(String planet, Variant variant, Size size);
}
public interface GalakPizzaDelivery {
List<Order> takeOrdersFromBestPlanet();
long countStandingOrders();
}
public interface GalakPizzaService extends GalakPizzaDelivery,
GalakPizzaOrders{
}
Select best blanet...
SELECT o.planet, count(o) FROM Order o
GROUP BY o.planet ORDER BY count(o) desc
Other Planet (but almost same story)
@Entity
@Table(name="T_PLANET",
indexes = {@Index(name="cnt_idx", columnList = "count", unique = false)} )
@NamedQueries( {
@NamedQuery(name = "select best planet from table", query = "SELECT p FROM Planet p " +
" ORDER BY p.count desc")})
public class Planet {
@Id
public final String name;
private int count;
protected Planet() {
name = "default";
}
public Planet(String name) {
this.name = name;
}
public int getCount() {
return this.count;
}
public void increment() {
this.count++;
}
public void clear() {
this.count = 0;
}
}
Other service implementation
public class GalakPizza implements GalakPizzaService {
final SessionFactory sessionFactory;
public GalakPizza(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
public long placeOrder(String planet, Variant variant, Size size) {
...
}
public List<Order> takeOrdersFromBestPlanet() {
...
}
public long countStandingOrders() {
...
}
}
Other - Place order
public long placeOrder(String planet, Variant variant, Size size) {
return this.runInSession(session -> {
final Order orderEntity = new Order(planet, variant, size);
final Long key = (Long) session.save(orderEntity);
incrementPlanetCounter(planet, session);
return key;
});
}
private void incrementPlanetCounter(String planet, Session session) {
Planet planetEntity = session.get(Planet.class, planet);
if (planetEntity == null) {
planetEntity = new Planet(planet);
session.save(planetEntity);
}
planetEntity.increment();
}
private <T> T runOnSession(Function<Session, T> dbCommand) { ...}
Other - runInSession
private <T> T runInSession(Function<Session, T> dbCommand) {
final Session session = sessionFactory.openSession();
session.beginTransaction();
try {
final T result = dbCommand.apply(session);
session.getTransaction().commit();
session.close();
return result;
} catch (ConstraintViolationException cve) {
session.getTransaction().rollback();
session.close();
return runInSession(dbCommand);
} catch (Throwable t) {
t.printStackTrace();
throw new RuntimeException(t);
}
}
So easy
Other - Take orders
public List<Order> takeOrdersFromBestPlanet() {
return this.runInSession(session -> {
final Query bestPlanetQuery = session.getNamedQuery("SELECT p FROM Planet p " +
" ORDER BY p.count desc");
bestPlanetQuery.setMaxResults(1);
final Iterator<Planet> bestPlanetsIterator = bestPlanetQuery.iterate();
if (bestPlanetsIterator.hasNext()) {
final Planet bestOne = bestPlanetsIterator.next();
final Query ordersQuery = session.getNamedQuery("SELECT o FROM Order o WHERE
o.planet = :planet");
ordersQuery.setParameter("planet", bestOne.name);
final List<Order> orders = ordersQuery.list();
orders.forEach(o -> session.delete(o));
bestOne.clear();
return orders;
}
return Collections.EMPTY_LIST;
});
}
Other – count orders
@Override
public long countStandingOrders() {
return this.runInSession(session -> {
final Query ordersCount = session.getNamedQuery("count orders");
final Long cnt = (Long) ordersCount.iterate().next();
return cnt;
});
}
Other - others
● Hibernate config, init
● MySql config
After one day of coding...
In a real galaxy
That we can simulate as
●
Customers - 4 Threads doing in loop placeOrder (random
planet name, variant and size) – no pauses
●
PizzBoy - 1 Thread doing in loop takeBestOrder – no pauses
●
Owners – 2 Threads doing in loop – countStandingOrders
Galaxy simulation
public static void main(String... args) {
runSimulation(5000);
System.gc();
sleep();
Result result = runSimulation(SECONDS_TOTAL*1000);
System.out.println("Orders processed:" + result.processed);
System.out.println("p/s:" + (double)result.processed/(double)
SECONDS_TOTAL);
System.out.println("Orders seen:" + result.seen);
System.out.println("o/s:" + (double)result.seen/(double)
SECONDS_TOTAL);
}
?
Normal universe Other universe
~40 000 p/s ~600 p/s
Processed orders
Normal universe Other universe
~ 12 823 500 p/s ~6362 p/s
Peeping speed
Normal universe Other universe
Normal universe Other universe
GODS of SQL
HELP! ME
Normal universe Other universe
~60 000 p/s ~1000 p/s
After few days of operations...
Normal universe Other universe
Cool, that it runs on
laptop
Reality strickes back
I do not trust PizzaBoy
I want to know where exactly were pizzas delivered
Normal universe Other universe
Cool, we will not delete
orders any more,
only mark them
as deleted!
Cool, we will add a list
that will be processed
during takeOrders,
or maybe
we will store data
in DB Table (as archive)
Reality strickes back
I do not trust PizzaBoy
I want to know where were pizzas delivered
Yesterday!!!
Normal universe Other universe
Crap...
We will restart system
and commands
will be reprocessed
Yet another real world case
System evolves
I want to let people compose their pizza/
Like: more cheese on one half,
and no meat on the next half,
And onion on the third half.
Normal universe Other universe
We will map it with only 20 tables
Or do we add TEXT field?
public Order(long id, String
planet, Supplier<Variant>
pizzaDescription, Size size) {
public Order(long id, String
planet, Variant variant, Size
size) {
We will use factory
Different
+ Fast
+ Code in Java
+ Flexible
+ Testable
- Sophisticated java
- Terribly slow
- Code in Strings and
Annotations
- Limited domain
- Testing expensive
+ Easy java
Why different ?
Long time ago
Sweet spot known as 90's
●
Computers had mostly one CPU Core
●
Memory (RAM) was expensive but more as 100MB
available in single unit
●
Disks were slow but huge (like 2Gb-20Gb)
●
Time for JEE
Around galactic year 2003
Normal universe
●
RAM is so cheap and huge
●
Computers have multiple cores
●
Alien developers start to use full power of hardware with
Java
●
No need to store data in databases anymore
●
Because RAM is so cheap and huge
Other universe
●
RAM is cheap and huge
●
Computers have multiple cores
●
But alien developers have never realised that
Other universe is a good place
●
Database vendors earn money and are happy
●
Application Servers vendors earn money and are happy
●
Power plants are happy
●
Hardware vendors are happy
●
Only business complains – but they still pay
●
Developers have a lot more work to do – they are happy..
Gfx By pressfoto / Freepik
DB / ORM vs Prevalence Problems
Problem Prevalent (Normal) ORMs (Other)
Detached objects Yes Yes
Transaction
isolation
Yes in JAVA
(concurrency)
Yes in DB
Testing Trivial Awful
Cache It is all cache Lots of configs...
Magic Contained Everywhere
Mapping All serializable goes Limited
If you want to jump to normal universe...
Simple start
●
Prevayler
or
●
Airomem (Prevayler wrapper for Java 8 )
or
●
Nothing :-)
Airomem quick - maven
<dependency>
<groupId>pl.setblack</groupId>
<artifactId>airomem-core</artifactId>
<version>1.0.5</version>
</dependency>
Airomem - init
PersistenceController<GalakPizzaCore,GalakPizzaCore> controller =
controller = PrevaylerBuilder
.newBuilder()
.withinUserFolder("pizza")
.useSupplier( () -> new GalakPizzaCore())
.build();
GalakPizzaCore is main/plain object - Root aggregate!
Must be Serializable! (how bad)
Airomem – commands
controller.executeAndQuery( core->core.placeOrder(planet, variant, size ));
----------------------
controller.executeAndQuery( new PlaceOrderCommand(planet,variant,size));
private static final class PlaceOrderCommand implements Command<GalakPizzaCore, Long>
{
private final String planet;
private final Variant variant;
private final Size size;
public PlaceOrderCommand(String planet, Variant variant, Size size){
this.planet = planet;
this.variant = variant;
this.size = size;
}
public Long execute(GalakPizzaCore system) {
return system.placeOrder(planet,variant, size);
}
}
Commands are never executed concurrently
Query
controller.query( c->c.countStandingOrders());
Queries are executed concurrently - also with
one command!
Airomem – snapshots, events
jarek@ubuntu:~$ cd prevayler/
jarek@ubuntu:~/prevayler$ ls
pizza
jarek@ubuntu:~/prevayler$ cd pizza/
jarek@ubuntu:~/prevayler/pizza$ ls -al
total 188
drwxrwxr-x 2 jarek jarek 4096 May 6 14:46 .
drwxrwxr-x 3 jarek jarek 4096 Apr 26 13:40 ..
-rw-rw-r-- 1 jarek jarek 675 Apr 26 14:17 0000000000000000001.journal
-rw-rw-r-- 1 jarek jarek 3375 Apr 26 14:18 0000000000000000002.journal
-rw-rw-r-- 1 jarek jarek 3369 May 5 10:51 0000000000000000007.journal
-rw-rw-r-- 1 jarek jarek 683 May 5 13:48 0000000000000000012.journal
-rw-rw-r-- 1 jarek jarek 2048 May 5 14:12 0000000000000000012.snapshot
-rw-rw-r-- 1 jarek jarek 497 May 5 14:12 0000000000000000013.journal
-rw-rw-r-- 1 jarek jarek 1849 May 5 14:15 0000000000000000013.snapshot
-rw-rw-r-- 1 jarek jarek 497 May 5 14:15 0000000000000000014.journal
-rw-rw-r-- 1 jarek jarek 1685 May 5 14:17 0000000000000000014.snapshot
-rw-rw-r-- 1 jarek jarek 8086 May 5 14:19 0000000000000000015.journal
-rw-rw-r-- 1 jarek jarek 1084 May 6 13:25 0000000000000000028.snapshot
-rw-rw-r-- 1 jarek jarek 57977 May 6 14:05 0000000000000000029.journal
-rw-rw-r-- 1 jarek jarek 1228 May 6 14:46 0000000000000000132.snapshot
-rw-rw-r-- 1 jarek jarek 59021 May 8 04:28 0000000000000000133.journal
Problems?
RAM?
Data migration
●
Not big deal in fact
●
Java Serialization (sth to learn)
●
readResolve, writeReplace
●
XML export option
Transaction
This is always transactional!!!
public Long execute(GalakPizzaCore system) {
return system.placeOrder(planet,variant, size);
}
Concurrency
Learn java.util.concurrent, synchronized or die!
Replication/ failover
Not in standard... but
Trivial to implement - send events to other machines, share
folder
Indices
Indices in memory do exists
CQEngine
Query<Car> query1 = or(endsWith(Car.NAME, "vic"),
lessThan(Car.CAR_ID, 2));
for (Car car : cars.retrieve(query1)) {
System.out.println(car);
}
Airomem summary
CQRS simplified - one command one event→
With RAM projection
Advice
Remember to add Thread.sleep(1000) often
Storing in Prevayler vs DB
●
Store facts
●
Shared state is a cache
●
Domain not polluted with magic
●
Clean architecture
Alternatives
●
Lagom
●
Akka persistence
●
CQRS generally
End
●
Try on something small first (not bigger then one planet)
●
Drop DB from core of your system
●
Drop your application server
●
Drop annotations
●
Drop magic
●
Learn Java and algorithms
●
Feel the power of RAM and CPU alltogether!

Contenu connexe

Tendances

The Ring programming language version 1.10 book - Part 34 of 212
The Ring programming language version 1.10 book - Part 34 of 212The Ring programming language version 1.10 book - Part 34 of 212
The Ring programming language version 1.10 book - Part 34 of 212Mahmoud Samir Fayed
 
The Ring programming language version 1.3 book - Part 85 of 88
The Ring programming language version 1.3 book - Part 85 of 88The Ring programming language version 1.3 book - Part 85 of 88
The Ring programming language version 1.3 book - Part 85 of 88Mahmoud Samir Fayed
 
The Ring programming language version 1.5.1 book - Part 12 of 180
The Ring programming language version 1.5.1 book - Part 12 of 180The Ring programming language version 1.5.1 book - Part 12 of 180
The Ring programming language version 1.5.1 book - Part 12 of 180Mahmoud Samir Fayed
 
The Ring programming language version 1.10 book - Part 81 of 212
The Ring programming language version 1.10 book - Part 81 of 212The Ring programming language version 1.10 book - Part 81 of 212
The Ring programming language version 1.10 book - Part 81 of 212Mahmoud Samir Fayed
 
Racing To Win: Using Race Conditions to Build Correct and Concurrent Software
Racing To Win: Using Race Conditions to Build Correct and Concurrent SoftwareRacing To Win: Using Race Conditions to Build Correct and Concurrent Software
Racing To Win: Using Race Conditions to Build Correct and Concurrent SoftwareFastly
 
JJUG CCC 2011 Spring
JJUG CCC 2011 SpringJJUG CCC 2011 Spring
JJUG CCC 2011 SpringKiyotaka Oku
 
The Ring programming language version 1.9 book - Part 48 of 210
The Ring programming language version 1.9 book - Part 48 of 210The Ring programming language version 1.9 book - Part 48 of 210
The Ring programming language version 1.9 book - Part 48 of 210Mahmoud Samir Fayed
 
The Ring programming language version 1.10 book - Part 46 of 212
The Ring programming language version 1.10 book - Part 46 of 212The Ring programming language version 1.10 book - Part 46 of 212
The Ring programming language version 1.10 book - Part 46 of 212Mahmoud Samir Fayed
 
MongoDB Chicago - MapReduce, Geospatial, & Other Cool Features
MongoDB Chicago - MapReduce, Geospatial, & Other Cool FeaturesMongoDB Chicago - MapReduce, Geospatial, & Other Cool Features
MongoDB Chicago - MapReduce, Geospatial, & Other Cool Featuresajhannan
 
Codepot - Pig i Hive: szybkie wprowadzenie / Pig and Hive crash course
Codepot - Pig i Hive: szybkie wprowadzenie / Pig and Hive crash courseCodepot - Pig i Hive: szybkie wprowadzenie / Pig and Hive crash course
Codepot - Pig i Hive: szybkie wprowadzenie / Pig and Hive crash courseSages
 
Java: Nie popełniaj tych błędów!
Java: Nie popełniaj tych błędów!Java: Nie popełniaj tych błędów!
Java: Nie popełniaj tych błędów!Daniel Pokusa
 
John Melesky - Federating Queries Using Postgres FDW @ Postgres Open
John Melesky - Federating Queries Using Postgres FDW @ Postgres OpenJohn Melesky - Federating Queries Using Postgres FDW @ Postgres Open
John Melesky - Federating Queries Using Postgres FDW @ Postgres OpenPostgresOpen
 
The Ring programming language version 1.5.2 book - Part 11 of 181
The Ring programming language version 1.5.2 book - Part 11 of 181The Ring programming language version 1.5.2 book - Part 11 of 181
The Ring programming language version 1.5.2 book - Part 11 of 181Mahmoud Samir Fayed
 
The Ring programming language version 1.10 book - Part 22 of 212
The Ring programming language version 1.10 book - Part 22 of 212The Ring programming language version 1.10 book - Part 22 of 212
The Ring programming language version 1.10 book - Part 22 of 212Mahmoud Samir Fayed
 
The Ring programming language version 1.7 book - Part 73 of 196
The Ring programming language version 1.7 book - Part 73 of 196The Ring programming language version 1.7 book - Part 73 of 196
The Ring programming language version 1.7 book - Part 73 of 196Mahmoud Samir Fayed
 
Wprowadzenie do technologi Big Data i Apache Hadoop
Wprowadzenie do technologi Big Data i Apache HadoopWprowadzenie do technologi Big Data i Apache Hadoop
Wprowadzenie do technologi Big Data i Apache HadoopSages
 
The Ring programming language version 1.9 book - Part 90 of 210
The Ring programming language version 1.9 book - Part 90 of 210The Ring programming language version 1.9 book - Part 90 of 210
The Ring programming language version 1.9 book - Part 90 of 210Mahmoud Samir Fayed
 
10b. Graph Databases Lab
10b. Graph Databases Lab10b. Graph Databases Lab
10b. Graph Databases LabFabio Fumarola
 

Tendances (20)

The Ring programming language version 1.10 book - Part 34 of 212
The Ring programming language version 1.10 book - Part 34 of 212The Ring programming language version 1.10 book - Part 34 of 212
The Ring programming language version 1.10 book - Part 34 of 212
 
The Ring programming language version 1.3 book - Part 85 of 88
The Ring programming language version 1.3 book - Part 85 of 88The Ring programming language version 1.3 book - Part 85 of 88
The Ring programming language version 1.3 book - Part 85 of 88
 
WOTC_Import
WOTC_ImportWOTC_Import
WOTC_Import
 
The Ring programming language version 1.5.1 book - Part 12 of 180
The Ring programming language version 1.5.1 book - Part 12 of 180The Ring programming language version 1.5.1 book - Part 12 of 180
The Ring programming language version 1.5.1 book - Part 12 of 180
 
The Ring programming language version 1.10 book - Part 81 of 212
The Ring programming language version 1.10 book - Part 81 of 212The Ring programming language version 1.10 book - Part 81 of 212
The Ring programming language version 1.10 book - Part 81 of 212
 
Racing To Win: Using Race Conditions to Build Correct and Concurrent Software
Racing To Win: Using Race Conditions to Build Correct and Concurrent SoftwareRacing To Win: Using Race Conditions to Build Correct and Concurrent Software
Racing To Win: Using Race Conditions to Build Correct and Concurrent Software
 
JJUG CCC 2011 Spring
JJUG CCC 2011 SpringJJUG CCC 2011 Spring
JJUG CCC 2011 Spring
 
The Ring programming language version 1.9 book - Part 48 of 210
The Ring programming language version 1.9 book - Part 48 of 210The Ring programming language version 1.9 book - Part 48 of 210
The Ring programming language version 1.9 book - Part 48 of 210
 
The Ring programming language version 1.10 book - Part 46 of 212
The Ring programming language version 1.10 book - Part 46 of 212The Ring programming language version 1.10 book - Part 46 of 212
The Ring programming language version 1.10 book - Part 46 of 212
 
MongoDB Chicago - MapReduce, Geospatial, & Other Cool Features
MongoDB Chicago - MapReduce, Geospatial, & Other Cool FeaturesMongoDB Chicago - MapReduce, Geospatial, & Other Cool Features
MongoDB Chicago - MapReduce, Geospatial, & Other Cool Features
 
Codepot - Pig i Hive: szybkie wprowadzenie / Pig and Hive crash course
Codepot - Pig i Hive: szybkie wprowadzenie / Pig and Hive crash courseCodepot - Pig i Hive: szybkie wprowadzenie / Pig and Hive crash course
Codepot - Pig i Hive: szybkie wprowadzenie / Pig and Hive crash course
 
Java: Nie popełniaj tych błędów!
Java: Nie popełniaj tych błędów!Java: Nie popełniaj tych błędów!
Java: Nie popełniaj tych błędów!
 
John Melesky - Federating Queries Using Postgres FDW @ Postgres Open
John Melesky - Federating Queries Using Postgres FDW @ Postgres OpenJohn Melesky - Federating Queries Using Postgres FDW @ Postgres Open
John Melesky - Federating Queries Using Postgres FDW @ Postgres Open
 
Full Text Search in PostgreSQL
Full Text Search in PostgreSQLFull Text Search in PostgreSQL
Full Text Search in PostgreSQL
 
The Ring programming language version 1.5.2 book - Part 11 of 181
The Ring programming language version 1.5.2 book - Part 11 of 181The Ring programming language version 1.5.2 book - Part 11 of 181
The Ring programming language version 1.5.2 book - Part 11 of 181
 
The Ring programming language version 1.10 book - Part 22 of 212
The Ring programming language version 1.10 book - Part 22 of 212The Ring programming language version 1.10 book - Part 22 of 212
The Ring programming language version 1.10 book - Part 22 of 212
 
The Ring programming language version 1.7 book - Part 73 of 196
The Ring programming language version 1.7 book - Part 73 of 196The Ring programming language version 1.7 book - Part 73 of 196
The Ring programming language version 1.7 book - Part 73 of 196
 
Wprowadzenie do technologi Big Data i Apache Hadoop
Wprowadzenie do technologi Big Data i Apache HadoopWprowadzenie do technologi Big Data i Apache Hadoop
Wprowadzenie do technologi Big Data i Apache Hadoop
 
The Ring programming language version 1.9 book - Part 90 of 210
The Ring programming language version 1.9 book - Part 90 of 210The Ring programming language version 1.9 book - Part 90 of 210
The Ring programming language version 1.9 book - Part 90 of 210
 
10b. Graph Databases Lab
10b. Graph Databases Lab10b. Graph Databases Lab
10b. Graph Databases Lab
 

Similaire à DROPDB Galactic story

JDD 2016 - Jaroslaw Ratajski - DROP DATABASE – przypowieść galaktyczna
JDD 2016 - Jaroslaw Ratajski - DROP DATABASE – przypowieść galaktyczna JDD 2016 - Jaroslaw Ratajski - DROP DATABASE – przypowieść galaktyczna
JDD 2016 - Jaroslaw Ratajski - DROP DATABASE – przypowieść galaktyczna PROIDEA
 
Rule Your Geometry with the Terraformer Toolkit
Rule Your Geometry with the Terraformer ToolkitRule Your Geometry with the Terraformer Toolkit
Rule Your Geometry with the Terraformer ToolkitAaron Parecki
 
Code level change propagation in virtual platform
Code level change propagation in virtual platformCode level change propagation in virtual platform
Code level change propagation in virtual platformHaiderAli650468
 
2017 02-07 - elastic & spark. building a search geo locator
2017 02-07 - elastic & spark. building a search geo locator2017 02-07 - elastic & spark. building a search geo locator
2017 02-07 - elastic & spark. building a search geo locatorAlberto Paro
 
2017 02-07 - elastic & spark. building a search geo locator
2017 02-07 - elastic & spark. building a search geo locator2017 02-07 - elastic & spark. building a search geo locator
2017 02-07 - elastic & spark. building a search geo locatorAlberto Paro
 
Demoiselle Spatial Latinoware 2011
Demoiselle Spatial Latinoware 2011Demoiselle Spatial Latinoware 2011
Demoiselle Spatial Latinoware 2011Rafael Soto
 
Android Architecure Components - introduction
Android Architecure Components - introductionAndroid Architecure Components - introduction
Android Architecure Components - introductionPaulina Szklarska
 
Scala @ TechMeetup Edinburgh
Scala @ TechMeetup EdinburghScala @ TechMeetup Edinburgh
Scala @ TechMeetup EdinburghStuart Roebuck
 
Kotlin 1.2: Sharing code between platforms
Kotlin 1.2: Sharing code between platformsKotlin 1.2: Sharing code between platforms
Kotlin 1.2: Sharing code between platformsKirill Rozov
 
Andriy Slobodyanyk "How to Use Hibernate: Key Problems and Solutions"
Andriy Slobodyanyk "How to Use Hibernate: Key Problems and Solutions"Andriy Slobodyanyk "How to Use Hibernate: Key Problems and Solutions"
Andriy Slobodyanyk "How to Use Hibernate: Key Problems and Solutions"LogeekNightUkraine
 
Geospatial Enhancements in MongoDB 2.4
Geospatial Enhancements in MongoDB 2.4Geospatial Enhancements in MongoDB 2.4
Geospatial Enhancements in MongoDB 2.4MongoDB
 
Best of build 2021 - C# 10 & .NET 6
Best of build 2021 -  C# 10 & .NET 6Best of build 2021 -  C# 10 & .NET 6
Best of build 2021 - C# 10 & .NET 6Moaid Hathot
 
Kotlin @ Coupang Backend 2017
Kotlin @ Coupang Backend 2017Kotlin @ Coupang Backend 2017
Kotlin @ Coupang Backend 2017Sunghyouk Bae
 
Apache Wicket and Java EE sitting in a tree
Apache Wicket and Java EE sitting in a treeApache Wicket and Java EE sitting in a tree
Apache Wicket and Java EE sitting in a treeMartijn Dashorst
 

Similaire à DROPDB Galactic story (20)

JDD 2016 - Jaroslaw Ratajski - DROP DATABASE – przypowieść galaktyczna
JDD 2016 - Jaroslaw Ratajski - DROP DATABASE – przypowieść galaktyczna JDD 2016 - Jaroslaw Ratajski - DROP DATABASE – przypowieść galaktyczna
JDD 2016 - Jaroslaw Ratajski - DROP DATABASE – przypowieść galaktyczna
 
Rule Your Geometry with the Terraformer Toolkit
Rule Your Geometry with the Terraformer ToolkitRule Your Geometry with the Terraformer Toolkit
Rule Your Geometry with the Terraformer Toolkit
 
Realm to Json & Royal
Realm to Json & RoyalRealm to Json & Royal
Realm to Json & Royal
 
Code level change propagation in virtual platform
Code level change propagation in virtual platformCode level change propagation in virtual platform
Code level change propagation in virtual platform
 
2017 02-07 - elastic & spark. building a search geo locator
2017 02-07 - elastic & spark. building a search geo locator2017 02-07 - elastic & spark. building a search geo locator
2017 02-07 - elastic & spark. building a search geo locator
 
2017 02-07 - elastic & spark. building a search geo locator
2017 02-07 - elastic & spark. building a search geo locator2017 02-07 - elastic & spark. building a search geo locator
2017 02-07 - elastic & spark. building a search geo locator
 
Demoiselle Spatial Latinoware 2011
Demoiselle Spatial Latinoware 2011Demoiselle Spatial Latinoware 2011
Demoiselle Spatial Latinoware 2011
 
Android Architecure Components - introduction
Android Architecure Components - introductionAndroid Architecure Components - introduction
Android Architecure Components - introduction
 
Hw09 Hadoop + Clojure
Hw09   Hadoop + ClojureHw09   Hadoop + Clojure
Hw09 Hadoop + Clojure
 
Hadoop + Clojure
Hadoop + ClojureHadoop + Clojure
Hadoop + Clojure
 
Hadoop
HadoopHadoop
Hadoop
 
Scala @ TechMeetup Edinburgh
Scala @ TechMeetup EdinburghScala @ TechMeetup Edinburgh
Scala @ TechMeetup Edinburgh
 
Kotlin 1.2: Sharing code between platforms
Kotlin 1.2: Sharing code between platformsKotlin 1.2: Sharing code between platforms
Kotlin 1.2: Sharing code between platforms
 
Andriy Slobodyanyk "How to Use Hibernate: Key Problems and Solutions"
Andriy Slobodyanyk "How to Use Hibernate: Key Problems and Solutions"Andriy Slobodyanyk "How to Use Hibernate: Key Problems and Solutions"
Andriy Slobodyanyk "How to Use Hibernate: Key Problems and Solutions"
 
Geospatial Enhancements in MongoDB 2.4
Geospatial Enhancements in MongoDB 2.4Geospatial Enhancements in MongoDB 2.4
Geospatial Enhancements in MongoDB 2.4
 
Best of build 2021 - C# 10 & .NET 6
Best of build 2021 -  C# 10 & .NET 6Best of build 2021 -  C# 10 & .NET 6
Best of build 2021 - C# 10 & .NET 6
 
Kotlin @ Coupang Backend 2017
Kotlin @ Coupang Backend 2017Kotlin @ Coupang Backend 2017
Kotlin @ Coupang Backend 2017
 
Apache Wicket and Java EE sitting in a tree
Apache Wicket and Java EE sitting in a treeApache Wicket and Java EE sitting in a tree
Apache Wicket and Java EE sitting in a tree
 
Spark_Documentation_Template1
Spark_Documentation_Template1Spark_Documentation_Template1
Spark_Documentation_Template1
 
Geolocation
GeolocationGeolocation
Geolocation
 

Plus de Jarek Ratajski

Pure Kotlin Devoxx PL 2021
Pure Kotlin Devoxx PL 2021Pure Kotlin Devoxx PL 2021
Pure Kotlin Devoxx PL 2021Jarek Ratajski
 
Transaction is a monad
Transaction is a  monadTransaction is a  monad
Transaction is a monadJarek Ratajski
 
Spring, CDI, Jakarta EE good parts
Spring, CDI, Jakarta EE good partsSpring, CDI, Jakarta EE good parts
Spring, CDI, Jakarta EE good partsJarek Ratajski
 
Eta lang Beauty And The Beast
Eta lang Beauty And The Beast Eta lang Beauty And The Beast
Eta lang Beauty And The Beast Jarek Ratajski
 
Another programming language - jeszcze jeden język
Another programming language - jeszcze jeden językAnother programming language - jeszcze jeden język
Another programming language - jeszcze jeden językJarek Ratajski
 
Beauty and the beast - Haskell on JVM
Beauty and the beast  - Haskell on JVMBeauty and the beast  - Haskell on JVM
Beauty and the beast - Haskell on JVMJarek Ratajski
 
Fighting null with memes
Fighting null with memesFighting null with memes
Fighting null with memesJarek Ratajski
 
Geecon walking in CODE
Geecon walking in CODEGeecon walking in CODE
Geecon walking in CODEJarek Ratajski
 
Scalaworld lambda core hardcore
Scalaworld lambda core hardcoreScalaworld lambda core hardcore
Scalaworld lambda core hardcoreJarek Ratajski
 

Plus de Jarek Ratajski (16)

respect-estimates.pdf
respect-estimates.pdfrespect-estimates.pdf
respect-estimates.pdf
 
Pure Kotlin Devoxx PL 2021
Pure Kotlin Devoxx PL 2021Pure Kotlin Devoxx PL 2021
Pure Kotlin Devoxx PL 2021
 
Lambda hardcore
Lambda hardcoreLambda hardcore
Lambda hardcore
 
Pure kotlin
Pure kotlinPure kotlin
Pure kotlin
 
Transaction is a monad
Transaction is a  monadTransaction is a  monad
Transaction is a monad
 
Scala to assembly
Scala to assemblyScala to assembly
Scala to assembly
 
Spring, CDI, Jakarta EE good parts
Spring, CDI, Jakarta EE good partsSpring, CDI, Jakarta EE good parts
Spring, CDI, Jakarta EE good parts
 
Eta lang Beauty And The Beast
Eta lang Beauty And The Beast Eta lang Beauty And The Beast
Eta lang Beauty And The Beast
 
Another programming language - jeszcze jeden język
Another programming language - jeszcze jeden językAnother programming language - jeszcze jeden język
Another programming language - jeszcze jeden język
 
Beauty and the beast - Haskell on JVM
Beauty and the beast  - Haskell on JVMBeauty and the beast  - Haskell on JVM
Beauty and the beast - Haskell on JVM
 
Fighting null with memes
Fighting null with memesFighting null with memes
Fighting null with memes
 
Eta
EtaEta
Eta
 
Geecon walking in CODE
Geecon walking in CODEGeecon walking in CODE
Geecon walking in CODE
 
Scalaworld lambda core hardcore
Scalaworld lambda core hardcoreScalaworld lambda core hardcore
Scalaworld lambda core hardcore
 
Lambda core
Lambda coreLambda core
Lambda core
 
[4 dev] lagom
[4 dev] lagom[4 dev] lagom
[4 dev] lagom
 

Dernier

Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...stazi3110
 
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideBuilding Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideChristina Lin
 
chapter--4-software-project-planning.ppt
chapter--4-software-project-planning.pptchapter--4-software-project-planning.ppt
chapter--4-software-project-planning.pptkotipi9215
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providermohitmore19
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdfWave PLM
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...harshavardhanraghave
 
Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...OnePlan Solutions
 
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...ICS
 
DNT_Corporate presentation know about us
DNT_Corporate presentation know about usDNT_Corporate presentation know about us
DNT_Corporate presentation know about usDynamic Netsoft
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...MyIntelliSource, Inc.
 
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdfThe Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdfkalichargn70th171
 
Project Based Learning (A.I).pptx detail explanation
Project Based Learning (A.I).pptx detail explanationProject Based Learning (A.I).pptx detail explanation
Project Based Learning (A.I).pptx detail explanationkaushalgiri8080
 
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...gurkirankumar98700
 
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer DataAdobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer DataBradBedford3
 
EY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityEY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityNeo4j
 
Salesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantSalesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantAxelRicardoTrocheRiq
 
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...MyIntelliSource, Inc.
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsAlberto González Trastoy
 

Dernier (20)

Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
 
Call Girls In Mukherjee Nagar 📱 9999965857 🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...
Call Girls In Mukherjee Nagar 📱  9999965857  🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...Call Girls In Mukherjee Nagar 📱  9999965857  🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...
Call Girls In Mukherjee Nagar 📱 9999965857 🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...
 
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideBuilding Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
 
chapter--4-software-project-planning.ppt
chapter--4-software-project-planning.pptchapter--4-software-project-planning.ppt
chapter--4-software-project-planning.ppt
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service provider
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
 
Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...
 
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
 
DNT_Corporate presentation know about us
DNT_Corporate presentation know about usDNT_Corporate presentation know about us
DNT_Corporate presentation know about us
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
 
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdfThe Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
 
Exploring iOS App Development: Simplifying the Process
Exploring iOS App Development: Simplifying the ProcessExploring iOS App Development: Simplifying the Process
Exploring iOS App Development: Simplifying the Process
 
Project Based Learning (A.I).pptx detail explanation
Project Based Learning (A.I).pptx detail explanationProject Based Learning (A.I).pptx detail explanation
Project Based Learning (A.I).pptx detail explanation
 
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
 
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer DataAdobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
 
EY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityEY_Graph Database Powered Sustainability
EY_Graph Database Powered Sustainability
 
Salesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantSalesforce Certified Field Service Consultant
Salesforce Certified Field Service Consultant
 
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
 

DROPDB Galactic story

  • 2. Jarek Ratajski Developer, wizard, anarchitectDeveloper, wizard, anarchitect Lives in LuzernLives in Luzern Works in CSS InsuranceWorks in CSS Insurance C64, 6502, 68000, 8086, C++, Java, JEE, Scala, Akka, JS,C64, 6502, 68000, 8086, C++, Java, JEE, Scala, Akka, JS, ScalaJS....ScalaJS.... jratajski@gmail.comjratajski@gmail.com @jarek000000@jarek000000
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 10. I know only one history Who cares?
  • 13. 10 000 Planets 3 Variants 3 Sizes HAWAII MARGHERITTA VEGETARIAN MEDIUM LARGE XL Domain summary
  • 14. MARGHERITTA MEDIUM HAWAII LARGE HAWAII LARGE VEGERARIAN LARGE HAWAII XL MARGHERITTA XL HAWAII LARGE HAWAII LARGE HAWAII LARGE HAWAII LARGE 33 33 11 11 Delivery model
  • 15. 10 000 Pizzas / s I want to look at number of queued orders 10000 times / s My wife also! Requirements
  • 16. Alien development (in 2 „parallel“ universes)
  • 17. Normal universe Other universe ++
  • 19. Normal domain public class Order implements Serializable { private static final long serialVersionUID = 1L; public final long id; public final String planet; public final Variant variant; public final Size size; public Order(long id, String planet, Variant variant, Size size) { this.id = id; this.planet = planet; this.size = size; this.variant = variant; } }
  • 20. Normal domain 2 public enum Size { MEDIUM, LARGE, XL } public enum Variant { HAWAII, MARGHERITA, VEGETARIAN }
  • 21. Normal Service public interface GalakPizzaOrders { long placeOrder(String planet, Variant variant, Size size); }
  • 22. Normal Service public interface GalakPizzaOrders { long placeOrder(String planet, Variant variant, Size size); } public interface GalakPizzaDelivery { List<Order> takeOrdersFromBestPlanet(); long countStandingOrders(); }
  • 23. Normal Service public interface GalakPizzaOrders { long placeOrder(String planet, Variant variant, Size size); } public interface GalakPizzaDelivery { List<Order> takeOrdersFromBestPlanet(); long countStandingOrders(); } public interface GalakPizzaService extends GalakPizzaDelivery, GalakPizzaOrders{ }
  • 24. Normal service implementation... public class GalakPizzaCore implements GalakPizzaService, Serializable, Storable<GalakPizzaCore> { public long placeOrder(String planet, Variant variant, Size size) { ... } public List<Order> takeOrdersFromBestPlanet() { ... } public long countStandingOrders() { ... } }
  • 25. Normal service implementation... public class GalakPizzaCore implements GalakPizzaService, Serializable, Storable<GalakPizzaCore> { private finalprivate final Map<String, List<Order>>Map<String, List<Order>> ordersorders == newnew HashMap<>();HashMap<>(); public long placeOrder(String planet, Variant variant, Size size) { ... } public List<Order> takeOrdersFromBestPlanet() { ... } public long countStandingOrders() { ... } }
  • 26. Normal service implementation... public class GalakPizzaCore implements GalakPizzaService, Serializable, Storable<GalakPizzaCore> { private finalprivate final Map<String, PlanetOrders>Map<String, PlanetOrders> ordersorders == newnew HashMap<>();HashMap<>(); public long placeOrder(String planet, Variant variant, Size size) { ... } public List<Order> takeOrdersFromBestPlanet() { ... } public long countStandingOrders() { ... } }
  • 27. PlanetOrders - helper class PlanetOrders implements Serializable { final String name; private List<Order> orders = new ArrayList<>(); public PlanetOrders(String name) { this.name = name; } ... }
  • 28. PlanetOrders - helper class PlanetOrders implements Serializable { final String name; private List<Order> orders = new ArrayList<>(); public PlanetOrders(String name) { this.name = name; } void assignOrder(final Order order) { this.orders.add(order); } ... }
  • 29. PlanetOrders - helper class PlanetOrders implements Serializable { final String name; private List<Order> orders = new ArrayList<>(); public PlanetOrders(String name) { this.name = name; } void assignOrder(final Order order) { this.orders.add(order); } public boolean isEmpty() { return this.orders.isEmpty(); } ... }
  • 30. Normal place order public class GalakPizzaCore implements GalakPizzaService, Serializable, Storable<GalakPizzaCore> { private final Map<String, PlanetOrders> orders = new HashMap<>(); private long orderSequence = 1; public long placeOrder(String planet, Variant variant, Size size) { final long id = orderSequence++; final Order order = new Order(id, planet, variant, size); assignOrderToPlanet(order); return id; }
  • 31. Normal place order public class GalakPizzaCore implements GalakPizzaService, Serializable, Storable<GalakPizzaCore> { private final Map<String, PlanetOrders> orders = new HashMap<>(); private long orderSequence = 1; public long placeOrder(String planet, Variant variant, Size size) { final long id = orderSequence++; final Order order = new Order(id, planet, variant, size); assignOrderToPlanet(order); return id; } private void assignOrderToPlanet(Order order) { final PlanetOrders po = orders.computeIfAbsent(order.planet, planetName -> new PlanetOrders(planetName)); po.assignOrder(order); ...
  • 32. Normal place order public class GalakPizzaCore implements GalakPizzaService, Serializable, Storable<GalakPizzaCore> { private final Map<String, PlanetOrders> orders = new HashMap<>(); private long orderSequence = 1; private AtomicLong ordersTotal = new AtomicLong(0); public long placeOrder(String planet, Variant variant, Size size) { final long id = orderSequence++; final Order order = new Order(id, planet, variant, size); assignOrderToPlanet(order); ordersTotal.incrementAndGet(); return id; } private void assignOrderToPlanet(Order order) { final PlanetOrders po = orders.computeIfAbsent(order.planet, planetName -> new PlanetOrders(planetName)); po.assignOrder(order); ...
  • 33. Normal place order revisited public class GalakPizzaCore { ... private final Map<String, PlanetOrders> orders = new HashMap<>(); private PriorityQueue<PlanetOrders> bestPlanets = new PriorityQueue<>(256); private long orderSequence = 1; private AtomicLong ordersTotal = new AtomicLong(0); public long placeOrder(String planet, Variant variant, Size size) { final long id = orderSequence++; final Order order = new Order(id, planet, variant, size); assignOrderToPlanet(order); ordersTotal.incrementAndGet(); return id; } private void assignOrderToPlanet(Order order) { final PlanetOrders po = orders.computeIfAbsent(order.planet, planetName -> new PlanetOrders(planetName)); po.assignOrder(order); this.bestPlanets.offer(po); }
  • 34. Normal place order revisited public class GalakPizzaCore { ... private final Map<String, PlanetOrders> orders = new HashMap<>(); private PriorityQueue<PlanetOrders> bestPlanets = new PriorityQueue<>(256); private long orderSequence = 1; private AtomicLong ordersTotal = new AtomicLong(0); public long placeOrder(String planet, Variant variant, Size size) { final long id = orderSequence++; final Order order = new Order(id, planet, variant, size); assignOrderToPlanet(order); ordersTotal.incrementAndGet(); return id; } private void assignOrderToPlanet(Order order) { final PlanetOrders po = orders.computeIfAbsent(order.planet, planetName -> new PlanetOrders(planetName)); po.assignOrder(order); this.bestPlanets.offer(po); BAD BAD BAD BAD }
  • 35. Normal place order revisited public class GalakPizzaCore { ... private final Map<String, PlanetOrders> orders = new HashMap<>(); private PriorityQueue<PlanetOrders.Wrapper> bestPlanets = new PriorityQueue<>(256); private long orderSequence = 1; private AtomicLong ordersTotal = new AtomicLong(0); public long placeOrder(String planet, Variant variant, Size size) { final long id = orderSequence++; final Order order = new Order(id, planet, variant, size); assignOrderToPlanet(order); ordersTotal.incrementAndGet(); return id; } private void assignOrderToPlanet(Order order) { final PlanetOrders po = orders.computeIfAbsent(order.planet, planetName -> new PlanetOrders(planetName)); po.assignOrder(order); this.bestPlanets.offer(new PlanetOrders.Wrapper(po)); }
  • 36. Wrapper... yeah public static class Wrapper implements Comparable<Wrapper>,Serializable{ final PlanetOrders porders; final int size; //just keep it final public Wrapper(PlanetOrders porders) { this.porders = porders; this.size = porders.orders.size(); } @Override public int compareTo(final Wrapper other) { return other.size - this.size; } }
  • 37. PlanetOrders – take orders class PlanetOrders implements Serializable { final String name; private List<Order> orders = new ArrayList<>(); List<Order> takeOrders() { final List<Order> result = this.orders; this.orders = new ArrayList<>(); return result; } public boolean isEmpty() { return this.orders.isEmpty(); } }
  • 38. PlanetOrders – take orders class PlanetOrders implements Serializable { final String name; private List<Order> orders = new ArrayList<>(); List<Order> takeOrders() { final List<Order> result = this.orders; this.orders = new ArrayList<>(); //yes we MUTATE! return result; } public boolean isEmpty() { return this.orders.isEmpty(); } }
  • 39. CYPS 2(2) ZYPS 1(1) CYPS 2(2) ZYPS (1)ZYPS 2(2) + Order 1 Hawaii XL to ZYPS CYPS 2(2) ZYPS 1(0) Take Orders ZYPS 1(0) Take Orders IsEmpty => ignore
  • 40. Normal take orderspublic class GalakPizzaCore implements GalakPizzaService, Serializable, Storable<GalakPizzaCore> { privateprivate PriorityQueue<PlanetOrders.Wrapper>PriorityQueue<PlanetOrders.Wrapper> bestPlanetsbestPlanets == newnew PriorityQueue<>(PriorityQueue<>(256256);); private AtomicLong ordersTotal = new AtomicLong(0); public List<Order> takeOrdersFromBestPlanet() { final Optional<PlanetOrders> planetOpt = takeBestPlanet(); .... } private Optional<PlanetOrders> takeBestPlanet() { PlanetOrders.Wrapper planet = this.bestPlanets.poll(); while (planet != null && planet.porders.isEmpty()) { planet = this.bestPlanets.poll(); } return Optional.ofNullable(planet).map(p->p.porders); }
  • 41. Normal take orderspublic class GalakPizzaCore implements GalakPizzaService, Serializable, Storable<GalakPizzaCore> { privateprivate PriorityQueue<PlanetOrders.Wrapper>PriorityQueue<PlanetOrders.Wrapper> bestPlanetsbestPlanets == newnew PriorityQueue<>(PriorityQueue<>(256256);); private AtomicLong ordersTotal = new AtomicLong(0); public List<Order> takeOrdersFromBestPlanet() { final Optional<PlanetOrders> planetOpt = takeBestPlanet(); if (planetOpt.isPresent()) { final PlanetOrders planet = planetOpt.get(); List<Order> orders = planet.takeOrders(); return orders; } return Collections.EMPTY_LIST; } private Optional<PlanetOrders> takeBestPlanet() { PlanetOrders.Wrapper planet = this.bestPlanets.poll(); while (planet != null && planet.porders.isEmpty()) { planet = this.bestPlanets.poll(); } return Optional.ofNullable(planet).map(p->p.porders); }
  • 42. Normal take orderspublic class GalakPizzaCore implements GalakPizzaService, Serializable, Storable<GalakPizzaCore> { privateprivate PriorityQueue<PlanetOrders.Wrapper>PriorityQueue<PlanetOrders.Wrapper> bestPlanetsbestPlanets == newnew PriorityQueue<>(PriorityQueue<>(256256);); private AtomicLong ordersTotal = new AtomicLong(0); public List<Order> takeOrdersFromBestPlanet() { final Optional<PlanetOrders> planetOpt = takeBestPlanet(); if (planetOpt.isPresent()) { final PlanetOrders planet = planetOpt.get(); List<Order> orders = planet.takeOrders(); ordersTotal.addAndGet(-orders.size()); return orders; } return Collections.EMPTY_LIST; } private Optional<PlanetOrders> takeBestPlanet() { PlanetOrders.Wrapper planet = this.bestPlanets.poll(); while (planet != null && planet.porders.isEmpty()) { planet = this.bestPlanets.poll(); } return Optional.ofNullable(planet).map(p->p.porders); }
  • 43. Normal count orders private AtomicLong ordersTotal = new AtomicLong(0); public long countStandingOrders() { return this.ordersTotal.get(); }
  • 44. We have service - but do we deal with? ● Concurrency ● Persistence
  • 45. Normal - Alien service wrapper public class GalakPizza implements GalakPizzaService { final PersistenceController<GalakPizzaCore,GalakPizzaCore> controller; public GalakPizza() { controller = PrevaylerBuilder.newBuilder() .withinUserFolder("pizza") .useSupplier( () -> new GalakPizzaCore()) .disableRoyalFoodTester() .build(); } public long placeOrder(final String planet, final Variant variant, final Size size) { return controller.executeAndQuery( core -> core.placeOrder(planet,variant,size)); } public List<Order> takeOrdersFromBestPlanet() { return controller.executeAndQuery( core ->core.takeOrdersFromBestPlanet()); } public long countStandingOrders() { return controller.query( c->c.countStandingOrders()); } ... }
  • 46. Done!
  • 48. Other Domain @Entity @Table(name="T_ORDER") @NamedQueries( { @NamedQuery(name = "select best planet", query = "SELECT o.planet, count(o) FROM Order o " + " GROUP BY o.planet ORDER BY count(o) desc"), @NamedQuery(name = "select orders", query = "SELECT o FROM Order o WHERE o.planet = :planet"), @NamedQuery(name = "count orders", query = "SELECT count(o) FROM Order o ") }) public class Order { @Id @GeneratedValue(generator="increment") @GenericGenerator(name="increment", strategy = "increment") final long id; public final String planet; public final Variant variant; public final Size size; protected Order() { this("this is strange...", null, null); } public Order(String planet, Variant variant, Size size) { this.planet = planet; this.variant = variant; this.size = size; id = 0; } public long getId() { return id; } }
  • 49. Other domain (same as above) public enum Size { MEDIUM, LARGE, XL } public enum Variant { HAWAII, MARGHERITA, VEGETARIAN }
  • 50. It is in TABLE so it exists
  • 51. Other service (same) public interface GalakPizzaOrders { long placeOrder(String planet, Variant variant, Size size); } public interface GalakPizzaDelivery { List<Order> takeOrdersFromBestPlanet(); long countStandingOrders(); } public interface GalakPizzaService extends GalakPizzaDelivery, GalakPizzaOrders{ }
  • 52. Select best blanet... SELECT o.planet, count(o) FROM Order o GROUP BY o.planet ORDER BY count(o) desc
  • 53. Other Planet (but almost same story) @Entity @Table(name="T_PLANET", indexes = {@Index(name="cnt_idx", columnList = "count", unique = false)} ) @NamedQueries( { @NamedQuery(name = "select best planet from table", query = "SELECT p FROM Planet p " + " ORDER BY p.count desc")}) public class Planet { @Id public final String name; private int count; protected Planet() { name = "default"; } public Planet(String name) { this.name = name; } public int getCount() { return this.count; } public void increment() { this.count++; } public void clear() { this.count = 0; } }
  • 54. Other service implementation public class GalakPizza implements GalakPizzaService { final SessionFactory sessionFactory; public GalakPizza(SessionFactory sessionFactory) { this.sessionFactory = sessionFactory; } public long placeOrder(String planet, Variant variant, Size size) { ... } public List<Order> takeOrdersFromBestPlanet() { ... } public long countStandingOrders() { ... } }
  • 55. Other - Place order public long placeOrder(String planet, Variant variant, Size size) { return this.runInSession(session -> { final Order orderEntity = new Order(planet, variant, size); final Long key = (Long) session.save(orderEntity); incrementPlanetCounter(planet, session); return key; }); } private void incrementPlanetCounter(String planet, Session session) { Planet planetEntity = session.get(Planet.class, planet); if (planetEntity == null) { planetEntity = new Planet(planet); session.save(planetEntity); } planetEntity.increment(); } private <T> T runOnSession(Function<Session, T> dbCommand) { ...}
  • 56. Other - runInSession private <T> T runInSession(Function<Session, T> dbCommand) { final Session session = sessionFactory.openSession(); session.beginTransaction(); try { final T result = dbCommand.apply(session); session.getTransaction().commit(); session.close(); return result; } catch (ConstraintViolationException cve) { session.getTransaction().rollback(); session.close(); return runInSession(dbCommand); } catch (Throwable t) { t.printStackTrace(); throw new RuntimeException(t); } } So easy
  • 57. Other - Take orders public List<Order> takeOrdersFromBestPlanet() { return this.runInSession(session -> { final Query bestPlanetQuery = session.getNamedQuery("SELECT p FROM Planet p " + " ORDER BY p.count desc"); bestPlanetQuery.setMaxResults(1); final Iterator<Planet> bestPlanetsIterator = bestPlanetQuery.iterate(); if (bestPlanetsIterator.hasNext()) { final Planet bestOne = bestPlanetsIterator.next(); final Query ordersQuery = session.getNamedQuery("SELECT o FROM Order o WHERE o.planet = :planet"); ordersQuery.setParameter("planet", bestOne.name); final List<Order> orders = ordersQuery.list(); orders.forEach(o -> session.delete(o)); bestOne.clear(); return orders; } return Collections.EMPTY_LIST; }); }
  • 58. Other – count orders @Override public long countStandingOrders() { return this.runInSession(session -> { final Query ordersCount = session.getNamedQuery("count orders"); final Long cnt = (Long) ordersCount.iterate().next(); return cnt; }); }
  • 59. Other - others ● Hibernate config, init ● MySql config
  • 60. After one day of coding...
  • 61. In a real galaxy
  • 62. That we can simulate as ● Customers - 4 Threads doing in loop placeOrder (random planet name, variant and size) – no pauses ● PizzBoy - 1 Thread doing in loop takeBestOrder – no pauses ● Owners – 2 Threads doing in loop – countStandingOrders
  • 63. Galaxy simulation public static void main(String... args) { runSimulation(5000); System.gc(); sleep(); Result result = runSimulation(SECONDS_TOTAL*1000); System.out.println("Orders processed:" + result.processed); System.out.println("p/s:" + (double)result.processed/(double) SECONDS_TOTAL); System.out.println("Orders seen:" + result.seen); System.out.println("o/s:" + (double)result.seen/(double) SECONDS_TOTAL); }
  • 64. ?
  • 65. Normal universe Other universe ~40 000 p/s ~600 p/s Processed orders
  • 66. Normal universe Other universe ~ 12 823 500 p/s ~6362 p/s Peeping speed
  • 68. Normal universe Other universe GODS of SQL HELP! ME
  • 69. Normal universe Other universe ~60 000 p/s ~1000 p/s
  • 70. After few days of operations...
  • 72. Cool, that it runs on laptop
  • 73. Reality strickes back I do not trust PizzaBoy I want to know where exactly were pizzas delivered
  • 74. Normal universe Other universe Cool, we will not delete orders any more, only mark them as deleted! Cool, we will add a list that will be processed during takeOrders, or maybe we will store data in DB Table (as archive)
  • 75. Reality strickes back I do not trust PizzaBoy I want to know where were pizzas delivered Yesterday!!!
  • 76. Normal universe Other universe Crap... We will restart system and commands will be reprocessed
  • 77. Yet another real world case
  • 78. System evolves I want to let people compose their pizza/ Like: more cheese on one half, and no meat on the next half, And onion on the third half.
  • 79. Normal universe Other universe We will map it with only 20 tables Or do we add TEXT field? public Order(long id, String planet, Supplier<Variant> pizzaDescription, Size size) { public Order(long id, String planet, Variant variant, Size size) { We will use factory
  • 80. Different + Fast + Code in Java + Flexible + Testable - Sophisticated java - Terribly slow - Code in Strings and Annotations - Limited domain - Testing expensive + Easy java
  • 83. Sweet spot known as 90's ● Computers had mostly one CPU Core ● Memory (RAM) was expensive but more as 100MB available in single unit ● Disks were slow but huge (like 2Gb-20Gb) ● Time for JEE
  • 85. Normal universe ● RAM is so cheap and huge ● Computers have multiple cores ● Alien developers start to use full power of hardware with Java ● No need to store data in databases anymore ● Because RAM is so cheap and huge
  • 86. Other universe ● RAM is cheap and huge ● Computers have multiple cores ● But alien developers have never realised that
  • 87. Other universe is a good place ● Database vendors earn money and are happy ● Application Servers vendors earn money and are happy ● Power plants are happy ● Hardware vendors are happy ● Only business complains – but they still pay ● Developers have a lot more work to do – they are happy.. Gfx By pressfoto / Freepik
  • 88.
  • 89. DB / ORM vs Prevalence Problems Problem Prevalent (Normal) ORMs (Other) Detached objects Yes Yes Transaction isolation Yes in JAVA (concurrency) Yes in DB Testing Trivial Awful Cache It is all cache Lots of configs... Magic Contained Everywhere Mapping All serializable goes Limited
  • 90. If you want to jump to normal universe...
  • 91. Simple start ● Prevayler or ● Airomem (Prevayler wrapper for Java 8 ) or ● Nothing :-)
  • 92. Airomem quick - maven <dependency> <groupId>pl.setblack</groupId> <artifactId>airomem-core</artifactId> <version>1.0.5</version> </dependency>
  • 93. Airomem - init PersistenceController<GalakPizzaCore,GalakPizzaCore> controller = controller = PrevaylerBuilder .newBuilder() .withinUserFolder("pizza") .useSupplier( () -> new GalakPizzaCore()) .build(); GalakPizzaCore is main/plain object - Root aggregate! Must be Serializable! (how bad)
  • 94. Airomem – commands controller.executeAndQuery( core->core.placeOrder(planet, variant, size )); ---------------------- controller.executeAndQuery( new PlaceOrderCommand(planet,variant,size)); private static final class PlaceOrderCommand implements Command<GalakPizzaCore, Long> { private final String planet; private final Variant variant; private final Size size; public PlaceOrderCommand(String planet, Variant variant, Size size){ this.planet = planet; this.variant = variant; this.size = size; } public Long execute(GalakPizzaCore system) { return system.placeOrder(planet,variant, size); } }
  • 95. Commands are never executed concurrently
  • 96. Query controller.query( c->c.countStandingOrders()); Queries are executed concurrently - also with one command!
  • 97. Airomem – snapshots, events jarek@ubuntu:~$ cd prevayler/ jarek@ubuntu:~/prevayler$ ls pizza jarek@ubuntu:~/prevayler$ cd pizza/ jarek@ubuntu:~/prevayler/pizza$ ls -al total 188 drwxrwxr-x 2 jarek jarek 4096 May 6 14:46 . drwxrwxr-x 3 jarek jarek 4096 Apr 26 13:40 .. -rw-rw-r-- 1 jarek jarek 675 Apr 26 14:17 0000000000000000001.journal -rw-rw-r-- 1 jarek jarek 3375 Apr 26 14:18 0000000000000000002.journal -rw-rw-r-- 1 jarek jarek 3369 May 5 10:51 0000000000000000007.journal -rw-rw-r-- 1 jarek jarek 683 May 5 13:48 0000000000000000012.journal -rw-rw-r-- 1 jarek jarek 2048 May 5 14:12 0000000000000000012.snapshot -rw-rw-r-- 1 jarek jarek 497 May 5 14:12 0000000000000000013.journal -rw-rw-r-- 1 jarek jarek 1849 May 5 14:15 0000000000000000013.snapshot -rw-rw-r-- 1 jarek jarek 497 May 5 14:15 0000000000000000014.journal -rw-rw-r-- 1 jarek jarek 1685 May 5 14:17 0000000000000000014.snapshot -rw-rw-r-- 1 jarek jarek 8086 May 5 14:19 0000000000000000015.journal -rw-rw-r-- 1 jarek jarek 1084 May 6 13:25 0000000000000000028.snapshot -rw-rw-r-- 1 jarek jarek 57977 May 6 14:05 0000000000000000029.journal -rw-rw-r-- 1 jarek jarek 1228 May 6 14:46 0000000000000000132.snapshot -rw-rw-r-- 1 jarek jarek 59021 May 8 04:28 0000000000000000133.journal
  • 99. RAM?
  • 100. Data migration ● Not big deal in fact ● Java Serialization (sth to learn) ● readResolve, writeReplace ● XML export option
  • 101. Transaction This is always transactional!!! public Long execute(GalakPizzaCore system) { return system.placeOrder(planet,variant, size); }
  • 103. Replication/ failover Not in standard... but Trivial to implement - send events to other machines, share folder
  • 104. Indices Indices in memory do exists CQEngine Query<Car> query1 = or(endsWith(Car.NAME, "vic"), lessThan(Car.CAR_ID, 2)); for (Car car : cars.retrieve(query1)) { System.out.println(car); }
  • 105. Airomem summary CQRS simplified - one command one event→ With RAM projection
  • 106. Advice Remember to add Thread.sleep(1000) often
  • 107. Storing in Prevayler vs DB ● Store facts ● Shared state is a cache ● Domain not polluted with magic ● Clean architecture
  • 109. End ● Try on something small first (not bigger then one planet) ● Drop DB from core of your system ● Drop your application server ● Drop annotations ● Drop magic ● Learn Java and algorithms ● Feel the power of RAM and CPU alltogether!