... or: the proxy dilemma
This whole section contains some information which we collected during our own application programming, and here I'd like to report on some problems which I encountered. They can be very helpful for your application development in AMETAS because you can avoid the same pitfalls.
If I were an application programmer, I'd get frustrated and start to try work-arounds. But I am one of the AMETAS kernel maintainers, and so I start thinking about new releases.
The AMETAS API allows the creation of service proxies. These structures are intended to encapsulate the message handling between the Place User, which actually tries to simulate the well-known method-calling paradigm.

Proxy (anti-)pattern
Though proxies were originally planned to improve readability and maintainability, they turned out to introduce some evil and hard-to-track problems.
| Therefore, we neither recommend to use the still contained proxy classes for new projects, nor to create such patterns by yourself. It is not the problem of our implementation but a general problem of autonomous programming against event-oriented programming. |
The basic rule is:
Events win against autonomy.
That is, whenever you decide to develop your application in an event-oriented way, you must make sure that the autonomy is enforced. Otherwise, the event-handling will dominate the programming, making it hard to keep the autonomy at all.
There are basically two ways to design proxies: asynchronous proxies for implementing a parallel, asynchronous handling, and synchronous proxies for a more method-call-like behavior.
Asynchronous proxies
We give some detailed information about the event problems in the event section. In summary, it is not recommended to retrieve messages by using a thread which is not controlled by the Place User itself. The EventNotificator is a second thread launched by the Place which is used to notify the Place User about incoming events. For messages, the event transmits the message ID of the incoming message.
Asynchronous proxies could be used in the following way:
The usage of the proxy pattern implies that the communication is a request-response scheme. This might be the case for most service interactions, actually. On the other hand, launching a sequence of proxy calls requires to check what reply messages are associated with which requests.
In order to get the information, it is required to retrieve the message. This violates the recommendation to only wake it the main thread and to avoid getting messages by the notificator. Anyway, even if we did not care about this violation, we would need to store all these messages intenally, and we would have to answer the question how to prevent messages coming it at situations where the agent cannot react properly.
In other words, asynchronous proxies are not recommended.
Synchronous proxies
Synchronous proxies show a behavior that resembles that of normal method calls. The main routine waits until the method returns. But these proxies encounter the same trouble as the asynchronous proxies. By employing multithreading, the Place User must consider to receive responses from different services. This requires the retrieval of the messages within the proxy, but in many cases, the message was not directed to this proxy but to another one of the same Place User.
In other words, synchronous proxies are not recommended.
Core of the problem
The actual problem is the distributed message handling within the Place User, but the centralized access to the Place User via the mailbox system.
The message submission is not a problem, but the retrieval should be centralized at one point in the PU code. This is even more important when multithreading is used. If the PU started to communicate with different other Place Users, it must be prepared to dispatch incoming messages to the appropriate parts of its implementation. However, if the retrieval occurs at multiple points, this handling becomes very cumbersome.
| In the end, the programmer must care for the retrieval of the messages by himself. Spending some thoughts about that, you will quickly agree that all automatic retrieval of messages - in any kind - is equivalent to using events which inject complete messages instead of their IDs. |
Because: Where is the difference between a thread which injects the message into the agent state, and a component of the agent which, being triggered by the thread, automatically gets the message? It mght look pretty different in the code, but as for the program logic, there is no noticeable difference.
Summary
The problems we encountered and investigated in the context of using proxies brought us to the following conclusion:
Do not attempt to simulate common method-oriented programming in the agent code. Designing the PU code in a way which makes it resemble standard method calling code introduces subtle problems with message retrieval which is a consequence of the general architecture of the message passing system of AMETAS.
It is worthwhile to consider other programming patterns for agent-oriented programming. One of them was included in AMETAS right after the discovery of the proxy problem: the context-oriented programming. Contexts can be a considerable help for organising the communication with other Place Users. As a result, your code will require restructuring to make it compatible to the context and state-oriented approach.