<div dir="ltr">A few points : <div><br></div><div>The current fireAsync() method that has been voted for allows all this : </div><div>- calling of the observers in one different thread : just call fireAsycn(payload, singleThreadExecutorService) and you're done</div><div>- calling of the observers "in parallel" (I dont like this way of saying it, since it leads to confusion) is also possible by not passing any ES, or a more than one threaded ES</div><div>In both cases you can order events in a strict (call the events of priority N, wait for them to return, then call the next priotiry) or relax mode (call the events of priority N, then call the events of next priority without waiting for them to return). </div><div>There are two kinds of problems that need to be dealt with : </div><div>- fixing the 1.2 specification that does not say anything about thread / event firing / observation (there's a JIRA for that)</div><div>- state that you need to guarantee non-race conditions on mutable event payload in the case of concurrent observers, the easiest way (of course not the only one) being : provide immutable payload</div><div>- context propagation through threads : we really need to work on this point and find a clean way to do this, at least for non TX contexts (since TX cant be accessed concurrently for other reasons). </div><div><br></div><div>José</div><div><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">2015-03-19 13:09 GMT+01:00 Jozef Hartinger <span dir="ltr"><<a href="mailto:jharting@redhat.com" target="_blank">jharting@redhat.com</a>></span>:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div text="#000000" bgcolor="#FFFFFF"><span class="">
<br>
<div>On 03/18/2015 04:14 PM, Pete Muir
wrote:<br>
</div>
<blockquote type="cite">
I think I have misunderstood the async model that is being
proposed. We are proposing that all the observers of an event
fired asynchronously are all run on a single thread? (Not the
thread that fires the event, another thread, but the same thread
for each observer).</blockquote></span>
No, the current proposal is not that specific at this point do
define a particular architecture. The one you mentioned is one of
the possible options.<br>
<br>
It has certain advantages:<br>
- the caller of fireAsync() does not wait for observers to complete
so it is async for the caller<br>
- observer notification works the same as way as we know today
except that in a different thread<br>
- the common pattern of using mutable event payload on which
observers contribute would work fine - the payload does not need to
be thread-safe - it would be safely published to the notification
thread by the CDI implementation and there are no races between
observers<br>
- ordering (if needed) fits well<br>
<br>
Disadvantages<br>
- it does not eliminate the backward-compatibility problem
completely (different thread means different transaction context,
CDI contexts and thread locals)<br>
- observers are not called in parallel<br>
<br>
Another option would be to call the observers in parallel<br>
Advantages:<br>
- the caller of fireAsync() does not wait for observers to complete
so it is async for the caller<br>
- observers are independent of each other<br>
Disadvantages:<br>
- it does not eliminate the backward-compatibility problem
completely (different thread means different transaction context,
CDI contexts and thread locals)<br>
- the payload needs to be thread-safe<br>
- ordering would not work here<br>
- single event firing possibly results in multiple exceptions
(tricky for the caller to handle with CompletionStage API)<br>
<br>
Another option is to combine those two and by default call the
observers in parallel. If for some reason an observer depends on a
different observer (by means of priorities) then the container
guarantees that the partial ordering of observer notification is
met.<br>
<br>
Advantages:<br>
- the caller of fireAsync() does not wait for observers to complete
so it is async for the caller<br>
- observers are independent of each other<br>
- priority works the same in sync and async<br>
Disadvantages:<br>
- it does not eliminate the backward-compatibility problem
completely (different thread means different transaction context,
CDI contexts and thread locals)<br>
- the payload needs to be thread-safe<br>
- single event firing possibly results in multiple exceptions
(tricky for the caller to handle with CompletionStage API)<span class=""><br>
<br>
<br>
<blockquote type="cite">
<div><br>
</div>
<div>This would be a somewhat odd limitation in my mind.
It’s certainly *not* something that is semantically intuitive if
you have something like @Observes @Asynchronously on event
observers, which definitely implies the event observation is
asynchronous, not the event firing.</div>
</blockquote></span>
In the current proposal, @Observes @Asynchronously is just an
enabler (for backward compatibility) of async event firing. It alone
does not mean anything.<span class=""><br>
<blockquote type="cite">
<div><br>
</div>
<div>I would definitely prefer an asynchronous
observation model, which I can’t see as being remotely
compatible with observer ordering. The classic approach of using
callbacks to identify when a method is done is inherently more
powerful, and better understood.</div>
</blockquote></span>
So basically kind of EJB's @Asynchronous methods applied to
observers + a callback on event.fire()? The downside I can see here
is that the event.fire() caller never knows whether the call will
block or not whereas with event.fireAsync() it would be guaranteed
not to block.<div><div class="h5"><br>
<blockquote type="cite">
<div><br>
</div>
<div>Perhaps I’ve missed this, but what are the use cases
for wanting to specify that the observation is done async on the
observer? And how does this relate to the event firing methods
ability to get a callback? I suspect you would need to retrofit
the entire firing system to always return a callback if you
wanted to allow the observer to control whether it was async or
not.</div>
<div>
<div><br>
<div>
<blockquote type="cite">
<div>On 18 Mar 2015, at 10:11, Antoine
Sabot-Durand <<a href="mailto:antoine@sabot-durand.net" target="_blank">antoine@sabot-durand.net</a>>
wrote:</div>
<br>
<div>
<div style="word-wrap:break-word">
<div>Support of ordering in async event was
last discussed yesterday in this thread (<a href="http://cdi-development-mailing-list.1064426.n5.nabble.com/Update-on-Async-event-doc-td5711176.html" target="_blank">http://cdi-development-mailing-list.1064426.n5.nabble.com/Update-on-Async-event-doc-td5711176.html</a>)</div>
<div>I tend to agree with Jozef. It’s more
consistent for user to allow ordering in async event
as in sync.</div>
<div><br>
</div>
<div>Antoine</div>
<div><br>
</div>
<br>
<div>
<blockquote type="cite">
<div>Le 18 mars 2015 à 11:05, Romain
Manni-Bucau <<a href="mailto:rmannibucau@gmail.com" target="_blank">rmannibucau@gmail.com</a>>
a écrit :</div>
<br>
<div><br>
<span style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;line-height:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;float:none;display:inline!important">2015-03-18
11:03 GMT+01:00 Antoine Sabot-Durand<span> </span></span><span dir="ltr" style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;line-height:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><<a href="mailto:antoine@sabot-durand.net" target="_blank">antoine@sabot-durand.net</a>></span><span style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;line-height:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;float:none;display:inline!important">:</span><br style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;line-height:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">
<blockquote class="gmail_quote" style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;line-height:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
<div style="word-wrap:break-word"><br>
<div>
<blockquote type="cite">
<div>Le 18 mars 2015 à 10:53,
Romain Manni-Bucau <<a href="mailto:rmannibucau@gmail.com" target="_blank">rmannibucau@gmail.com</a>>
a écrit :</div>
<br>
<div>
<div dir="ltr">
<div class="gmail_extra">
<div>
<div>
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr"><br>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="gmail_quote"><span>2015-03-18 10:33
GMT+01:00 Antoine Sabot-Durand<span> </span><span dir="ltr"><<a href="mailto:antoine@sabot-durand.net" target="_blank">antoine@sabot-durand.net</a>></span>:<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
<div style="word-wrap:break-word"><br>
<div>
<blockquote type="cite">
<div>Le 18
mars 2015 à 09:58,
Romain Manni-Bucau
<<a href="mailto:rmannibucau@gmail.com" target="_blank">rmannibucau@gmail.com</a>>
a écrit :</div>
<span><br>
<div>
<div dir="ltr">
<div class="gmail_extra">
<div>
<div>
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr"><br>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="gmail_quote">2015-03-18
9:55 GMT+01:00
Antoine
Sabot-Durand<span> </span><span dir="ltr"><<a href="mailto:antoine@sabot-durand.net" target="_blank">antoine@sabot-durand.net</a>></span>:<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
<div style="word-wrap:break-word">
<div>
<blockquote type="cite">
<div><br>
Le 18 mars
2015 à 09:42,
Romain
Manni-Bucau
<<a href="mailto:rmannibucau@gmail.com" target="_blank">rmannibucau@gmail.com</a>>
a écrit :</div>
<span><br>
<div>
<div dir="ltr">Hi
guys,
<div><br>
</div>
<div>think
Mark is right
and a new API
(as fireAsync)
would be
better for
users for:</div>
<div>-
understanding</div>
<div>-
compatibility
(think to
custom
extensions
using this
flag)</div>
</div>
</div>
</span></blockquote>
<div><br>
</div>
<div>My
point here is
to avoid
making CDI the
EJB next by
introducing
@Async or
@Asynchronous
annotation in
the spec. This
kind of
annotation
should be
shared by
other specs
and would have
a better fit
in concurrency
utilities or
commons
annotations
spec.</div>
<span>
<div><br>
</div>
</span></div>
</div>
</blockquote>
<div><br>
</div>
<div>+1</div>
<div> </div>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
<div style="word-wrap:break-word">
<div><span>
<blockquote type="cite">
<div>
<div dir="ltr">
<div>that
said if we
have @Async
methods I
think async
observers are
really
useless, isn't
it?</div>
</div>
</div>
</blockquote>
<div><br>
</div>
</span>
<div>@Async
is rather
useless IMO
when you see
how easy it is
do async
operation with
Java 8. On the
other hand
Async
observers are
a at a higher
level since
they are
called thru
the Container
and that the
fire point
must know
what’s going
on at the
other side.</div>
<div>
<div><br>
</div>
</div>
</div>
</div>
</blockquote>
<div><br>
</div>
<div>don't
get it,
observer can
use j8 then to
do its stuff
asynchronously
so maybe the
feature if
finally
useless
assuming you
run on j8.</div>
</div>
</div>
</div>
</div>
</span></blockquote>
<div><br>
</div>
<div>And how do
you make your fire
point know that one of
its observer will be
asynchronous ? How do
you manage event
ordering (as we plan
to support it for
async event as well).
I think we shouldn’t
see the event bus as a
standard method call
but something more
featured (think about
parameter injection in
observer methods or
transactional
behavior)</div>
<span><br>
</span></div>
</div>
</blockquote>
<div><br>
</div>
</span>
<div>then this is not
asynchronism and just an
observer queue which is
something different IMO.</div>
</div>
</div>
</div>
</div>
</blockquote>
<div><br>
</div>
<div>From user pov it’s async :
"I fire an event and get the control
back right away". The impl will make an
observer queue in an other thread, but
the user exp is totally different than
classic fire().</div>
<span><br>
</span></div>
</div>
</blockquote>
<div style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;line-height:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><br>
</div>
<div style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;line-height:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">this
is discussable since it is not for 2
observers. If you use async it can be - often
- cause of a long processing, if you have 2
long computing methods then you sequentiallize
it which breaks the reason why you wanted
async, no? </div>
<blockquote class="gmail_quote" style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;line-height:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
<div style="word-wrap:break-word">
<div><span>
<blockquote type="cite">
<div>
<div dir="ltr">
<div class="gmail_extra">
<div class="gmail_quote">
<div> </div>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
<div style="word-wrap:break-word">
<div><span>
<blockquote type="cite">
<div>
<div dir="ltr">
<div class="gmail_extra">
<div class="gmail_quote">
<div><br>
</div>
<div>That
said saying a
method is
async is still
more elegant
than firing it
in a pool you
don't control.</div>
</div>
</div>
</div>
</div>
</blockquote>
<div><br>
</div>
</span>
<div>fireAsync
will have a signature
allowing you to pass
your own Executor to
give you better
control on thread pool</div>
<div>
<div><br>
</div>
</div>
</div>
</div>
</blockquote>
<div><br>
</div>
<div>a default one
should be bound to the bm -
main case IMO. having an app
executor is not a very nice
solution in term of API. </div>
</div>
</div>
</div>
</div>
</blockquote>
<div><br>
</div>
</span>
<div>Yes it was already
discussed, there will be 2 signatures
for fireAsync().</div>
<div>
<div>
<div><br>
</div>
<div><br>
</div>
<br>
<blockquote type="cite">
<div>
<div dir="ltr">
<div class="gmail_extra">
<div class="gmail_quote">
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
<div style="word-wrap:break-word">
<div>
<div>
<div>
<blockquote type="cite">
<div>
<div dir="ltr">
<div class="gmail_extra">
<div class="gmail_quote">
<div> </div>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
<div style="word-wrap:break-word">
<div>
<div>
<div>
<blockquote type="cite">
<div>
<div dir="ltr">
<div><br>
</div>
</div>
<div class="gmail_extra"><br clear="all">
<div>
<div>
<div dir="ltr">
<div>
<div dir="ltr">
<div>
<div dir="ltr">
<div>
<div dir="ltr">
<div><br>
<span style="font-size:small">Romain
Manni-Bucau</span><br>
<a href="https://twitter.com/rmannibucau" target="_blank">@rmannibucau</a><span> </span>| <a href="http://rmannibucau.wordpress.com/" target="_blank">Blog</a> |<span> </span><a href="https://github.com/rmannibucau" target="_blank">Github</a> |<span> </span><a href="https://www.linkedin.com/in/rmannibucau" target="_blank">LinkedIn</a> |<span> </span><a href="http://www.tomitribe.com/" target="_blank">Tomitriber</a></div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<br>
<div class="gmail_quote">2015-03-18
9:30 GMT+01:00
Arne Limburg<span> </span><span dir="ltr"><<a href="mailto:arne.limburg@openknowledge.de" target="_blank">arne.limburg@openknowledge.de</a>></span>:<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">Hi
Antoine,<br>
<br>
The third
bullet point
in 10.5.1 of
the CDI 1.1
spec states
that the<br>
observer
method must be
called in the
same
transaction
context as the<br>
event.fire(...)
if it is no
transactional
observer (that
is<br>
TransactionPhase.IN_PROGRESS).<br>
If the default
behavior would
be async, we
would have to
move the<br>
transaction
context to
another
thread. To my
best knowledge
this would be<br>
the only
situation in
EE where this
is the case.<br>
<br>
Cheers,<br>
Arne<br>
<br>
Am 18.03.15
09:21 schrieb
"Antoine
Sabot-Durand"
unter<br>
<div>
<div><<a href="mailto:antoine@sabot-durand.net" target="_blank">antoine@sabot-durand.net</a>>:<br>
<br>
>Hi Arne,<br>
><br>
>Sorry can
you explain
why? This
value allows
observer to be
called inside<br>
>or outside
a transaction.
What will be
the
compatibility
issue?<br>
><br>
>Antoine<br>
><br>
><br>
>> Le 18
mars 2015 à
09:05, Arne
Limburg <<a href="mailto:arne.limburg@openknowledge.de" target="_blank">arne.limburg@openknowledge.de</a>>
a<br>
>>écrit
:<br>
>><br>
>> Hi to
all,<br>
>><br>
>> I
think the
biggest issue
with backward
compatibility
is, that the<br>
>>current<br>
>>
@Observes
annotation by
default has
TransactionPhase.IN_PROGRESS.<br>
>> I
think we can¹t
deal with
this, if the
default for
observers
would be<br>
>>
async. So I
think there is
no way to
specify async
as default
without<br>
>>
loosing
backward
compatibility.<br>
>> Any
other
thoughts?<br>
>><br>
>>
Cheers,<br>
>> Arne<br>
>><br>
>><br>
>> Am
18.03.15 08:48
schrieb
"Antoine
Sabot-Durand"
unter<br>
>> <<a href="mailto:antoine@sabot-durand.net" target="_blank">antoine@sabot-durand.net</a>>:<br>
>><br>
>>>
Hi all,<br>
>>><br>
>>>
Yesterday we
had another
meeting to try
to find a
better
solution than<br>
>>>
explicitly
activating
async event on
observer,
without no
success. I<br>
>>>
understand
that we should
go on on this
feature so
what I suggest
is to<br>
>>>
have a meeting
(an hangout)
with people
that want to
try to find a<br>
>>>better<br>
>>>
solution. If
we find
something
we¹ll do a
last proposal,
and in all<br>
>>>case<br>
>>>
we¹ll adopt
the woking
solution next
week for this
point. People<br>
>>>
interested
with this
please
manifest
yourself.<br>
>>><br>
>>>
If we have to
go with opt-in
(have to
explicitly
declare an
observer<br>
>>>
supporting
async event)
we also have
to validate
the decision
to use a<br>
>>>
member in
@Observes (as
it was decided
before) or go
back on that
as<br>
>>>
mMark keep
asking by
introducing a
new annotation
to add on the<br>
>>>observer<br>
>>>
(@Async or
something
similar). As I
said when we
discussed this
point,<br>
>>>I<br>
>>>
prefer the
member in
@Observes but
we may have
overlooked
issues linked<br>
>>>
to backward
compatibility.<br>
>>> A
third solution
might be to
introduce an
@ObserveAsync
to declare an<br>
>>>
asynchronous
capable
observerŠ<br>
>>><br>
>>>
I¹m waiting
for active
feedback from
you to find
the best
solution<br>
>>>taking<br>
>>>
ALL aspects
(not only the
technicals
one) into
account.<br>
>>><br>
>>>
Thanks,<br>
>>><br>
>>>
Antoine<br>
>><br>
><br>
<br>
<br>
</div>
</div>
<div>
<div>_______________________________________________<br>
cdi-dev
mailing list<br>
<a href="mailto:cdi-dev@lists.jboss.org" target="_blank">cdi-dev@lists.jboss.org</a><br>
<a href="https://lists.jboss.org/mailman/listinfo/cdi-dev" target="_blank">https://lists.jboss.org/mailman/listinfo/cdi-dev</a><br>
<br>
Note that for
all code
provided on
this list, the
provider
licenses the
code under the
Apache
License,
Version 2 (<a href="http://www.apache.org/licenses/LICENSE-2.0.html" target="_blank">http://www.apache.org/licenses/LICENSE-2.0.html</a>).
For all other
ideas provided
on this list,
the provider
waives all
patent and
other
intellectual
property
rights
inherent in
such
information.</div>
</div>
</blockquote>
</div>
</div>
</div>
</blockquote>
</div>
</div>
</div>
</div>
</blockquote>
</div>
</div>
</div>
</div>
</blockquote>
</div>
</div>
</div>
</div>
</blockquote>
</div>
</div>
</div>
</div>
</blockquote>
</div>
</div>
</div>
</div>
</blockquote>
</div>
</blockquote>
</div>
<br>
</div>
_______________________________________________<br>
cdi-dev mailing list<br>
<a href="mailto:cdi-dev@lists.jboss.org" target="_blank">cdi-dev@lists.jboss.org</a><br>
<a href="https://lists.jboss.org/mailman/listinfo/cdi-dev" target="_blank">https://lists.jboss.org/mailman/listinfo/cdi-dev</a><br>
<br>
Note that for all code provided on this list, the
provider licenses the code under the Apache License,
Version 2
(<a href="http://www.apache.org/licenses/LICENSE-2.0.html" target="_blank">http://www.apache.org/licenses/LICENSE-2.0.html</a>). For
all other ideas provided on this list, the provider
waives all patent and other intellectual property rights
inherent in such information.</div>
</blockquote>
</div>
<br>
</div>
</div>
<br>
<fieldset></fieldset>
<br>
<pre>_______________________________________________
cdi-dev mailing list
<a href="mailto:cdi-dev@lists.jboss.org" target="_blank">cdi-dev@lists.jboss.org</a>
<a href="https://lists.jboss.org/mailman/listinfo/cdi-dev" target="_blank">https://lists.jboss.org/mailman/listinfo/cdi-dev</a>
Note that for all code provided on this list, the provider licenses the code under the Apache License, Version 2 (<a href="http://www.apache.org/licenses/LICENSE-2.0.html" target="_blank">http://www.apache.org/licenses/LICENSE-2.0.html</a>). For all other ideas provided on this list, the provider waives all patent and other intellectual property rights inherent in such information.</pre>
</blockquote>
<br>
</div></div></div>
<br>_______________________________________________<br>
cdi-dev mailing list<br>
<a href="mailto:cdi-dev@lists.jboss.org">cdi-dev@lists.jboss.org</a><br>
<a href="https://lists.jboss.org/mailman/listinfo/cdi-dev" target="_blank">https://lists.jboss.org/mailman/listinfo/cdi-dev</a><br>
<br>
Note that for all code provided on this list, the provider licenses the code under the Apache License, Version 2 (<a href="http://www.apache.org/licenses/LICENSE-2.0.html" target="_blank">http://www.apache.org/licenses/LICENSE-2.0.html</a>). For all other ideas provided on this list, the provider waives all patent and other intellectual property rights inherent in such information.<br></blockquote></div><br><br clear="all"><div><br></div>-- <br><div class="gmail_signature"><div><a href="http://blog.paumard.org" target="_blank">Java le soir</a> <a href="http://blog.paumard.org/cours-tutoriaux/" target="_blank">Cours Java en ligne</a></div><div><a href="http://twitter.com/#!/JosePaumard" target="_blank">Twitter</a> <a href="http://www.parisjug.org" target="_blank">Paris JUG</a> <a href="http://www.devoxx.fr" target="_blank">Devoxx France</a></div><div>M : +33 6 76 82 91 47</div></div>
</div>