SlideShare uma empresa Scribd logo
1 de 44
Baixar para ler offline
LEGACY APPLICATIONS
Piotr Pasich
Piotr Pasich @
FROM SPAGHETTI TO CODE
czyli dziedziczymy aplikację
DLACZEGO TEGO NIE PRZEPISAĆ?
Piotr Pasich @
dużo kodu
duża ilość funkcjonalności
czas
pieniądze
Piotr Pasich @
PREVENTING REGRESSIONS
czyli nic nie ruszać
Piotr Pasich @
TESTY FUNKCJONALNOŚCI
Selenium IDE, behat, testy jednostkowe
Piotr Pasich @
ŚRODOWISKO
minimum PHP 5.3.3
Sqlite3, JSON, ctype
php app/check.php
date.timezone set in php.ini
Phpcs CodeSniffs
tutaj po raz pierwszy korzystamy z testów
Piotr Pasich @
INSTALACJA SYMFONY 2
katalog legacy
namespace
Piotr Pasich @
namespace Legacy {
(...)
}
LegacyBundle
app/console generate:bundle
Bundle namespace: XsolveLegacyBundle
Piotr Pasich @
AUTOLOADER
<?php
namespace XsolveLegacyBundle;
require_once(__DIR__ . "/../../../legacy/index.php"); //disabled execute::run
use Legacy;
use SymfonyComponentHttpKernelBundleBundle;
use SymfonyComponentDependencyInjectionContainerBuilder;
class XsolveLegacyBundle extends Bundle
{
public function build(ContainerBuilder $container)
{
spl_autoload_register(array('Kohana', 'auto_load'));
}
}
Piotr Pasich @
MainAction
class LegacyController extends Controller
{
/**
* @Route("/", name="main_page")
* @Route("/{filename}.html", name="proxy_html", requirements={"filename" = ".+"})
* @Route("/{filename}", name="proxy", requirements={"filename" = ".+"})
*/
public function indexAction($filename='index')
{
$_SERVER['SCRIPT_URL'] = $filename.'.html';
$_SERVER['REQUEST_URI'] = $filename.'.html';
ob_start();
// include_once ('../legacy/index.php');
Event::run('system.routing');
Benchmark::stop(SYSTEM_BENCHMARK.'_system_initialization');
Event::run('system.execute');
$response = new Response(ob_get_clean());
return $response;
}
}
Piotr Pasich @
KOHANA?
system/core/Bootstrap.php
//Event::run('system.routing');
//Benchmark::stop(SYSTEM_BENCHMARK.'_system_initialization');
//Event::run('system.shutdown');
DIE; //!
Piotr Pasich @
LAYOUT
esi
Varnish
Guzzle Client
Crawler
Piotr Pasich @
ESI + VARNISH
http://todsul.com/symfony2-esi-varnish
framework: { esi: true }
Piotr Pasich @
ESI CONTROLLER
/**
* @Route(name="esi_center_column")
*/
public function getCenterColumnAction(Request $request)
{
$url = $request->get('url'); //almost like proxy.php
$html = $this->get('xsolve.legacy.client')->requestElement($url, '.
span-center');
return $this->get('xsolve.response.cache')->getResponseWithCache
($html, 10);
}
Piotr Pasich @
ESI SERVICE
class LegacyClient
{
(...)
public function requestElement($url, $element)
{
$html = $this->request($url);
return $this->filter($html, $element);
}
(...)
Piotr Pasich @
ESI SERVICE
/**
* @return SymfonyComponentDomCrawlerCrawler
*/
public function request($url)
{
if (!isset($this->response[$url])) {
$client = $this->getClient();
$request = $client->get($url);
$request->setHeader('Cookie', null);
$this->response[$url] = $request->send();
}
return $this->response[$url]->getBody();
}
Piotr Pasich @
ESI SERVICE
/**
* @return GuzzleHttpClient
*/
public function getClient()
{
$client = new Client();
return $client;
}
Piotr Pasich @
ESI SERVICE
public function filter($html, $element)
{
$crawler = new Crawler();
$crawler->addHtmlContent($html);
$crawler = $crawler->filter($element);
$html = '';
foreach ($crawler as $domElement) {
$html.= $domElement->ownerDocument->saveHTML($domElement);
}
return $html;
}
Piotr Pasich @
ESI SERVICE
public function filter($html, $element)
{
$crawler = new Crawler();
$crawler->addHtmlContent($html);
$crawler = $crawler->filter($element);
$html = '';
foreach ($crawler as $domElement) {
$html.= $domElement->ownerDocument->saveHTML($domElement);
}
return $html;
}
Piotr Pasich @
HOW TO USE IT?
<!DOCTYPE html>
<html>
<esi:include src="{{ path('esi_head') }}" />
<body>
<div class="container with-background">
<esi:include src="{{ path('esi_left_column') }}" />
<div class="span-center">
{% block content %}
{% endblock %}
</div>
<esi:include src="{{ path('esi_right_column') }}" />
<esi:include src="{{ path('esi_footer') }}" />
</div>
</body>
</html>
Piotr Pasich @
REVERSE PROXY CACHE
// app/AppCache.php
require_once __DIR__.'/AppKernel.php';
use SymfonyBundleFrameworkBundleHttpCacheHttpCache;
class AppCache extends HttpCache
{
protected function getOptions()
{
return array(
'debug' => false,
'default_ttl' => 0,
'private_headers' => array('Authorization', 'Cookie'),
'allow_reload' => true,
'allow_revalidate' => false,
'stale_while_revalidate' => 2,
'stale_if_error' => 60,
);
}
}
Piotr Pasich @
REVERSE PROXY CACHE
<?php
// web/app.php
require_once __DIR__.'/../app/bootstrap.php.cache';
require_once __DIR__.'/../app/AppKernel.php';
require_once __DIR__.'/../app/AppCache.php';
use SymfonyComponentHttpFoundationRequest;
$kernel = new AppKernel('prod', false);
$kernel->loadClassCache();
// wrap the default AppKernel with the AppCache one
$kernel = new AppCache($kernel);
$request = Request::createFromGlobals();
$response = $kernel->handle($request);
$response->send();
$kernel->terminate($request, $response);
Piotr Pasich @
REVERSE PROXY CACHE
class ResponseCache {
public function getResponseWithCache($html, $cacheTime=1)
{
$response = new Response($html);
$response->setMaxAge($cacheTime);
$response->setSharedMaxAge($cacheTime);
$date = new DateTime();
$date->modify("+$cacheTime seconds");
$response->setExpires($date);
return $response;
}
}
Piotr Pasich @
RENDER
{% render url('latest_news', { 'max': 5 }) with {}, {'standalone': true} %}
Piotr Pasich @
ROUTING
namespace XsolveLegacyBundleService;
class LegacyRouter
{
/** @var array Legacy routes configuration */
protected $config;
public function __construct(Router $router)
{
include __DIR__.'/../../../../legacy/application/config/urls.php';
$this->config = $config;
$this->router = $router;
$this->locale = $this->router->getContext()->getParameter('_locale');
}
// (..)
}
Piotr Pasich @
KONFIGURACJA
class LegacyConfiguration
{
protected $configuration;
public function __construct($configuration)
{
$this->configuration = $configuration;
}
public function onKernelRequest(GetResponseEvent $event)
{
global $legacyConfig;
$legacyConfig = $this->configuration;
}
}
Piotr Pasich @
KONFIGURACJA
global $legacyConfig;
$config['default'] = $legacyConfig['database']['default'];
$config['import'] = $legacyConfig['database']['import'];
Piotr Pasich @
SESSION
Gdzie jest problem?
_s2_(...)
Piotr Pasich @
SESSION
class RequestListener {
public function onKernelRequest(GetResponseEvent $event) {
$bags = array(
'total_hits',
'_kf_flash_',
'user_agent',
'last_activity',
'search.criteria',
'category.name',
'auth_user'
);
foreach ($bags as $namespace) {
$bag = new AttributeBag($namespace, '.');
$bag->setName($namespace);
$this->session->registerBag($bag);
}
}
}
Piotr Pasich @
SESSION
namespace XsolveLegacyBundleSession;
use SymfonyComponentHttpFoundationSessionAttributeAttributeBagInterface;
use SymfonyComponentHttpFoundationSessionSessionBagInterface;
use XsolveLegacyBundleSessionScalarBagInterface;
/**
* This class provides scalar storage of session attributes using
* a name spacing character in the key.
*
* @author Piotr Pasich <piotr.pasich@xsolve.pl>
*/
class ScalarBag implements ScalarBagInterface, SessionBagInterface
{
// (...)
}
Piotr Pasich @
REQUEST LISTENER
<?xml version="1.0" ?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.
com/schema/dic/services/services-1.0.xsd">
<services>
<service id="xsolve.legacy.listener.request" class="XsolveLegacyBundleRequestListener"
>
<tag name="kernel.event_listener" event="kernel.request" method="onKernelRequest"/>
<argument type="service" id="session" />
</service>
</services>
</container>
Piotr Pasich @
NIE DZIAŁA!
DLACZEGO?
Piotr Pasich @
BO KOHANA!
class Session_Core {
// (...)
public function create($vars = NULL)
{
$this->destroy();
// (...)
}
}
Piotr Pasich @
TERAZ DZIAŁA
class Session_Core {
// (...)
public function create($vars = NULL)
{
//$this->destroy();
// (...)
}
}
Piotr Pasich @
TERAZ NIE DZIAŁA
Piotr Pasich @
TERAZ DZIAŁA
class Session_Core {
// (...)
public function create($vars = NULL)
{
// Destroy any current sessions
self::$createCall = self::$createCall+1;
if (self::$createCall > 10){
$_SESSION = array();
}
// this->destroy();
// (...)
}
}
Piotr Pasich @
BAZA DANYCH
ponad 100 tabel = 100 encji
brak odpowiednich relacji
brak pełnej zgodności z wymogami Doctrine 2
Piotr Pasich @
BAZA DANYCH
app/console doctrine:mapping:import XsolveLegacyBundle annotation
Piotr Pasich @
KONFLIKTY I BŁĘDY
naprawiamy ręcznie :(
Piotr Pasich @
PRZEPISUJEMY
/**
* @Route("/{categoryName}.html")
*/
public function indexAction($categoryName)
{
$criterias = array( 'category' => $categoryName );
$offers = $this->get('legacy.offers')->getRandomOffers($criterias);
$view = $this->renderView('XsolveOfferBundle:Default:index.html.twig', array(
'offers' => $offers
));
return $this->get('legacy.response.cache')->getResponseWithCache($view, 2);
}
Piotr Pasich @
I TO DZIAŁA!
Piotr Pasich @
DZIĘKUJĘ ZA UWAGĘ
Piotr Pasich
piotr.pasich@xsolve.pl
www.xsolve.pl

Mais conteúdo relacionado

Mais procurados

The Joy of Smartmatch
The Joy of SmartmatchThe Joy of Smartmatch
The Joy of Smartmatch
Andrew Shitov
 
News of the Symfony2 World
News of the Symfony2 WorldNews of the Symfony2 World
News of the Symfony2 World
Fabien Potencier
 
Perl web frameworks
Perl web frameworksPerl web frameworks
Perl web frameworks
diego_k
 
Speed up your developments with Symfony2
Speed up your developments with Symfony2Speed up your developments with Symfony2
Speed up your developments with Symfony2
Hugo Hamon
 

Mais procurados (20)

Perl6 in-production
Perl6 in-productionPerl6 in-production
Perl6 in-production
 
The Joy of Smartmatch
The Joy of SmartmatchThe Joy of Smartmatch
The Joy of Smartmatch
 
POE
POEPOE
POE
 
BASH Variables Part 1: Basic Interpolation
BASH Variables Part 1: Basic InterpolationBASH Variables Part 1: Basic Interpolation
BASH Variables Part 1: Basic Interpolation
 
News of the Symfony2 World
News of the Symfony2 WorldNews of the Symfony2 World
News of the Symfony2 World
 
Perl 6 by example
Perl 6 by examplePerl 6 by example
Perl 6 by example
 
Metadata-driven Testing
Metadata-driven TestingMetadata-driven Testing
Metadata-driven Testing
 
Hypers and Gathers and Takes! Oh my!
Hypers and Gathers and Takes! Oh my!Hypers and Gathers and Takes! Oh my!
Hypers and Gathers and Takes! Oh my!
 
BSDM with BASH: Command Interpolation
BSDM with BASH: Command InterpolationBSDM with BASH: Command Interpolation
BSDM with BASH: Command Interpolation
 
I, For One, Welcome Our New Perl6 Overlords
I, For One, Welcome Our New Perl6 OverlordsI, For One, Welcome Our New Perl6 Overlords
I, For One, Welcome Our New Perl6 Overlords
 
Perl6 grammars
Perl6 grammarsPerl6 grammars
Perl6 grammars
 
PuppetCamp Ghent - What Not to Do with Puppet
PuppetCamp Ghent - What Not to Do with PuppetPuppetCamp Ghent - What Not to Do with Puppet
PuppetCamp Ghent - What Not to Do with Puppet
 
Puppet: What _not_ to do
Puppet: What _not_ to doPuppet: What _not_ to do
Puppet: What _not_ to do
 
Perl web frameworks
Perl web frameworksPerl web frameworks
Perl web frameworks
 
Perl6 Regexen: Reduce the line noise in your code.
Perl6 Regexen: Reduce the line noise in your code.Perl6 Regexen: Reduce the line noise in your code.
Perl6 Regexen: Reduce the line noise in your code.
 
Memory Manglement in Raku
Memory Manglement in RakuMemory Manglement in Raku
Memory Manglement in Raku
 
Symfony2 - WebExpo 2010
Symfony2 - WebExpo 2010Symfony2 - WebExpo 2010
Symfony2 - WebExpo 2010
 
The $path to knowledge: What little it take to unit-test Perl.
The $path to knowledge: What little it take to unit-test Perl.The $path to knowledge: What little it take to unit-test Perl.
The $path to knowledge: What little it take to unit-test Perl.
 
Speed up your developments with Symfony2
Speed up your developments with Symfony2Speed up your developments with Symfony2
Speed up your developments with Symfony2
 
Tobias Nyholm "Deep dive into Symfony 4 internals"
Tobias Nyholm "Deep dive into Symfony 4 internals"Tobias Nyholm "Deep dive into Symfony 4 internals"
Tobias Nyholm "Deep dive into Symfony 4 internals"
 

Semelhante a Legacy applications - 4Developes konferencja, Piotr Pasich

Zendcon 2007 Api Design
Zendcon 2007 Api DesignZendcon 2007 Api Design
Zendcon 2007 Api Design
unodelostrece
 
Javascript Continues Integration in Jenkins with AngularJS
Javascript Continues Integration in Jenkins with AngularJSJavascript Continues Integration in Jenkins with AngularJS
Javascript Continues Integration in Jenkins with AngularJS
Ladislav Prskavec
 
Kansai.pm 10周年記念 Plack/PSGI 入門
Kansai.pm 10周年記念 Plack/PSGI 入門Kansai.pm 10周年記念 Plack/PSGI 入門
Kansai.pm 10周年記念 Plack/PSGI 入門
lestrrat
 
Introducing PHP Latest Updates
Introducing PHP Latest UpdatesIntroducing PHP Latest Updates
Introducing PHP Latest Updates
Iftekhar Eather
 

Semelhante a Legacy applications - 4Developes konferencja, Piotr Pasich (20)

Zendcon 2007 Api Design
Zendcon 2007 Api DesignZendcon 2007 Api Design
Zendcon 2007 Api Design
 
Workshop quality assurance for php projects - ZendCon 2013
Workshop quality assurance for php projects - ZendCon 2013Workshop quality assurance for php projects - ZendCon 2013
Workshop quality assurance for php projects - ZendCon 2013
 
Javascript Continues Integration in Jenkins with AngularJS
Javascript Continues Integration in Jenkins with AngularJSJavascript Continues Integration in Jenkins with AngularJS
Javascript Continues Integration in Jenkins with AngularJS
 
Workshop quality assurance for php projects - phpbelfast
Workshop quality assurance for php projects - phpbelfastWorkshop quality assurance for php projects - phpbelfast
Workshop quality assurance for php projects - phpbelfast
 
Great Developers Steal
Great Developers StealGreat Developers Steal
Great Developers Steal
 
solving little problems
solving little problemssolving little problems
solving little problems
 
Codeigniter : Two Step View - Concept Implementation
Codeigniter : Two Step View - Concept ImplementationCodeigniter : Two Step View - Concept Implementation
Codeigniter : Two Step View - Concept Implementation
 
How to build a High Performance PSGI/Plack Server
How to build a High Performance PSGI/Plack Server How to build a High Performance PSGI/Plack Server
How to build a High Performance PSGI/Plack Server
 
Symfony2 - OSIDays 2010
Symfony2 - OSIDays 2010Symfony2 - OSIDays 2010
Symfony2 - OSIDays 2010
 
Kansai.pm 10周年記念 Plack/PSGI 入門
Kansai.pm 10周年記念 Plack/PSGI 入門Kansai.pm 10周年記念 Plack/PSGI 入門
Kansai.pm 10周年記念 Plack/PSGI 入門
 
Perforce Object and Record Model
Perforce Object and Record Model  Perforce Object and Record Model
Perforce Object and Record Model
 
Symfony2 - WebExpo 2010
Symfony2 - WebExpo 2010Symfony2 - WebExpo 2010
Symfony2 - WebExpo 2010
 
Building Lithium Apps
Building Lithium AppsBuilding Lithium Apps
Building Lithium Apps
 
Php on the desktop and php gtk2
Php on the desktop and php gtk2Php on the desktop and php gtk2
Php on the desktop and php gtk2
 
Introducing CakeEntity
Introducing CakeEntityIntroducing CakeEntity
Introducing CakeEntity
 
REST with Eve and Python
REST with Eve and PythonREST with Eve and Python
REST with Eve and Python
 
Introducing PHP Latest Updates
Introducing PHP Latest UpdatesIntroducing PHP Latest Updates
Introducing PHP Latest Updates
 
Debugging: Rules & Tools
Debugging: Rules & ToolsDebugging: Rules & Tools
Debugging: Rules & Tools
 
Debugging: Rules And Tools - PHPTek 11 Version
Debugging: Rules And Tools - PHPTek 11 VersionDebugging: Rules And Tools - PHPTek 11 Version
Debugging: Rules And Tools - PHPTek 11 Version
 
Introducing Assetic: Asset Management for PHP 5.3
Introducing Assetic: Asset Management for PHP 5.3Introducing Assetic: Asset Management for PHP 5.3
Introducing Assetic: Asset Management for PHP 5.3
 

Mais de Piotr Pasich

Simplify your code with annotations - SymfonyCon Warsaw 2013
Simplify your code with annotations - SymfonyCon Warsaw 2013Simplify your code with annotations - SymfonyCon Warsaw 2013
Simplify your code with annotations - SymfonyCon Warsaw 2013
Piotr Pasich
 
PHPConPl 2013 - Allowed memory size of X bytes exhausted
PHPConPl 2013 - Allowed memory size of X bytes exhaustedPHPConPl 2013 - Allowed memory size of X bytes exhausted
PHPConPl 2013 - Allowed memory size of X bytes exhausted
Piotr Pasich
 
SpreadIT - Make your project SOLID!
SpreadIT - Make your project SOLID! SpreadIT - Make your project SOLID!
SpreadIT - Make your project SOLID!
Piotr Pasich
 

Mais de Piotr Pasich (8)

Messaging queues with RabbitMQ
Messaging queues with RabbitMQMessaging queues with RabbitMQ
Messaging queues with RabbitMQ
 
How to write applications prepared for every cataclysm with Event Sourcing an...
How to write applications prepared for every cataclysm with Event Sourcing an...How to write applications prepared for every cataclysm with Event Sourcing an...
How to write applications prepared for every cataclysm with Event Sourcing an...
 
Varnish - Tips & Tricks - 4Developers 2015
Varnish - Tips & Tricks - 4Developers 2015Varnish - Tips & Tricks - 4Developers 2015
Varnish - Tips & Tricks - 4Developers 2015
 
Arduino - SymfonyCon 2014 Lighting Talks
Arduino - SymfonyCon 2014 Lighting TalksArduino - SymfonyCon 2014 Lighting Talks
Arduino - SymfonyCon 2014 Lighting Talks
 
Game of performance - Message Brokers behind the scenes
Game of performance - Message Brokers behind the scenesGame of performance - Message Brokers behind the scenes
Game of performance - Message Brokers behind the scenes
 
Simplify your code with annotations - SymfonyCon Warsaw 2013
Simplify your code with annotations - SymfonyCon Warsaw 2013Simplify your code with annotations - SymfonyCon Warsaw 2013
Simplify your code with annotations - SymfonyCon Warsaw 2013
 
PHPConPl 2013 - Allowed memory size of X bytes exhausted
PHPConPl 2013 - Allowed memory size of X bytes exhaustedPHPConPl 2013 - Allowed memory size of X bytes exhausted
PHPConPl 2013 - Allowed memory size of X bytes exhausted
 
SpreadIT - Make your project SOLID!
SpreadIT - Make your project SOLID! SpreadIT - Make your project SOLID!
SpreadIT - Make your project SOLID!
 

Último

EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
Earley Information Science
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
Enterprise Knowledge
 

Último (20)

Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
Tech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdfTech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdf
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
Evaluating the top large language models.pdf
Evaluating the top large language models.pdfEvaluating the top large language models.pdf
Evaluating the top large language models.pdf
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 

Legacy applications - 4Developes konferencja, Piotr Pasich