OASIS Mailing List ArchivesView the OASIS mailing list archive below
or browse/search using MarkMail.

 


Help: OASIS Mailing Lists Help | MarkMail Help

sca-assembly message

[Date Prev] | [Thread Prev] | [Thread Next] | [Date Next] -- [Date Index] | [Thread Index] | [List Home]


Subject: Re: [sca-assembly] Fwd: Conversational services


Thanks Dave.

I'll try to comment inline inline.

Jim

On Dec 18, 2008, at 1:28 PM, David Booz wrote:

Hi Jim,
Sorry for the long delay, took me a while to grok some of what you said.

In line is going to be hard, so I'll try to put responses here:

On the topic of interop:
----------------------------------------
1) Interop is about wire level communications. Multi-vendor Domains is broader than interop, IMHO, but never-the-less I agree that multi-vendor Domains are not a goal of SCA V1.1.
2) Ok, good but you don't say if conversations is part of this or not, and that's a critical point to understand.
3) Ok - but I don't see what this has to do with the main point of conversations in SCA as this about some other concept of conversations.
4) How is this fundamentally different from 3? At the moment, given the lack of a WS-Conversation spec, SCA conversations flowing over web services (or any other protocol for that matter) is just as non-standard as whatever MS does.
I would agree that 2,3/4,1 is the right priority.
However, one of the problems we have in SCA spec space is that we have no way to apply this conversation concept across the body of the specs, the bindings specs being the ones I focussed on here.

It seems it would be fair to say that in your use cases, you'd never expose a conversational semantic on one of the edge services?

I'd never say never but probably not. However, on the edge of a domain, we try to stay as basic and loosely coupled as possible. For our purposes, conversational interactions involve a tighter degree of coupling and generally shouldn't be done there (this is not to say its inappropriate for other cases). What we typically have are stateless services handling requests coming in from outside the domain via a number of different bindings and being processed by conversational services further down the invocation stack.  

That is, if conversational support were only available over binding.sca, you'd be ok with that? I wouldn't, which is one of the reasons I want to remove conversations (as an interface semantic) entirely from the specs.

I would actually be o.k. with that, not just with conversations but with any interaction semantic as long as it is possible to support using at least two bindings. In other words, I don't think we should be limiting SCA capabilities to the lowest common denominator as determined by an interopable protocol such as Web Services. If we do, I believe we will severely limit the utility of SCA for building applications. 

I believe this position has precedent in what we are doing with callbacks (e.g. there is no existing, industry accepted "WS-Callback". There was a spec by that name, but it didn't gain traction outside of BEA Workshop). We should take the same approach with conversations. 

However, I do see your point about treating conversations as an interface semantic. I sent a proposal to the Java mailing list where we would define conversations as an intent as opposed to an interface semantic. Does that sound like a valuable approach? This would potentially allow for bindings to "op-out" of supporting conversational interactions. It would also maintain backward compatibility with the existing SCA conversational mechanisms, causing minimal disruption for users which I feel is very important.

On the topic of the web service binding:
----------------------------------------------------------------------
I don't disagree with your assertions that a messaging backbone is important for a binding.sca implementation. I also agree that web services are a technology for the edge of the Domain. However, I think the important piece of info from your experience is that your application model is a homogeneous one, java components in a domain, interacting with one another. Your description leads me to thinking it's a greenfield situation. What a nice life that would be. If this is not a correct generalization, please help me understand.

Most of our components are Java (JVM)-based. However, our applications are unfortunately not greenfield (yes, it would be nice if they were). For example, they must interact with clients and services external to domain that use a variety of communications protocols.  We found the extensibility capabilities of SCA very useful in this respect as we were able to do such things as write a streaming FTP binding extension to our runtime.  

Based on my experience, which may be different from yours, this predominantly Java/JVM-bent is likely to be a very common enterprise architecture, particularly given the vendors backing SCA. 

Most of the use cases I'm concerned about are integration cases. Component implementations already exist, many of which are tied to specific protocols/transports. I see SCA as the unifying model, over top of these heterogeneous sets of services, which is why I started my original email with interop and WS questions.

I am concerned with integration too but it may be slightly different than what you are focusing on. Our applications must interface with external banking systems (it's inter-bank processing) that use a combination of interoperable (WS-*) and proprietary protocols. SCA has allowed us to significantly reduce the complexity of our systems that were previously using a combination of Spring and an ESB. In our case SCA has provided value as an integration technology in the following ways:

1. As a simplified programming model for connecting distributed subsystems. SCA has provided us with a powerful asynchronous and conversational model that works well with other technologies we use (e.g. JPA), modularity, protocol abstraction, and policy reuse. In these cases, SCA controls both sides of the wire (literally).

2. As a technology for connecting to external systems and exposing services to external clients. The real benefit here is policy reuse and to some extent protocol abstraction. The benefits around protocol abstraction are a "nice-to-have" but not essential since protocols used for external communication rarely change. By external systems, I mean either a client or a provider not hosted in the same SCA domain.

From our perspective, SCA offers clear benefits over existing technologies in the first scenario. If SCA was reduced to just handling scenario #2 we probably wouldn't be much interested in it and would look to an alternative. 

Mixing SCA conversations into this model has little value since none of the existing component models know what to do with them. The concept of conversations as we have defined it is not broadly recognized or understood. I can see how it would be valuable in the situations where all you have to work with are SCA Java components, but in my world those situations are rare. What is broadly recognized and accessible to these heterogeneous components is a shared context model (like activity session) that is based on the transactional model of participants with registered interest and a coordinator, thus I greatly prefer this latter model.

This is where I think out integration scenarios are different. We are using conversations and callbacks in the *processing* of requests coming into the domain and for internal domain operations, not as part of the contract for the service at the edge of the domain. More specifically, the "edge" service receives requests and delegates to a number of other services for processing. Once case we are using this is in processing very large documents (> 150MB) coming in using MTOM and FTP.

We are using SCA to create applications that are managed by a common infrastructure and must integrate with various external systems. We aren't using it as a way to link together loosely coupled but otherwise completely autonomous systems. If we were doing the latter, we would probably just use Web Services (the JAX-WS and .NET programming models are easy enough to use).

I am interested in understanding more about what you have in mind with respect to activity sessions/sets. I do have some preconceptions. First, I have to disagree with you on activity sessions/sets being more broadly understood than conversations. Although CORBA had the former, the conversational model we have corresponds to analogous features in the JAX-WS RI and .NET. I that context, I would be in favor of looking into interoperating with those stacks. In the future, richer semantics such as callbacks, conversations, or activity sessions may become more prevalent at the edge of the domain. However, in our case, I think it is going to be easier for us to convince our business partners to use JAX-WS or .NET as opposed to a proprietary activity session model.



>> The first is by having the client "request" a GUID from our conversational infrastructure.
Is this an API? The conversational concept was supposed to be an invisible, runtime implemented correlation mechanism. If the extension you describe is an API then it violates that principle by putting the GUID infrastructure into the face of the business logic programmer. This is one of the struggles we have with the existing model as avoiding this API is paramount. I'd rather not have standard conversations than standardize a hack in the face of the programmer. Vendors could experiment here and then standardize later after we get some experience.

I'm one of the strongest proponents of getting rid of as many APIs as is feasible. The conversation and callback simplification proposal I sent to the Java TC list substantially reduces the number of APIs. In the case of the GUID, it is obtained entirely transparently from the client application. A few months back, I sent detailed sequence diagrams to the Java TC mailing list on how this can be done that I could repost if people are interested.

>> propagate it via WS-A ReferenceParameters
This is a violation of the WS-A spec. Reference parameters are opaque to a client, they are only to be returned to a provider on subsequent invocations.

In my reading of the spec it is not. The reference parameter is opaque to the client. The parameter would be obtained from the "issuer of the endpoint reference" - in this case the domain. This would require either:

1. A handshake
2. Piggy-backing the reference parameter on either the return of a synchronous response or a callback

And would require that subsequent invocations not be delivered until the parameter is received. The sequence diagrams I drew up a while back demonstrate how this can be achieved. If the client and provider were both SCA components, this process would be transparent. The only time an extra step may be apparent is if a service provider had an operation that was marked to begin the conversation that was non-blocking and was called from a client over WS-*. I don't think that is too onerous given synchronous calls are much more common and they would be handled transparently.
  

>> Another way I have seen conversations propagated is how Microsoft Durable Services work using service-provider tokens. In this model, they have decoupled the conversational model from how correlation is transmitted (in SOAP headers via WsHttpContextBinding, or using cookies via BasicContextBinding). With this approach, one issue is that the SCA infrastructure will have to wait for a back channel message containing the token before a second invocation is delivered.
Two problems here. 1) This is a new protocol, that is not standardized, and 2) you will have to define how this works for each binding spec.

Aren't we already doing this for callbacks? If we restrict any remotable communication in SCA to be bound by what is provided in standardized protocols, we will effectively limit SCA to what is achievable using WS-*. That will preclude a range of very important features, including callbacks, that are essential to enterprise development. 

One area where we probably disagree is the issue of having to define how communications work for each binding spec. While it would be a nice to be able to define one communications model that works across all bindings for a majority of enterprise use cases, I don't believe that is realistic. In the Java TC, we have already seen how transacted messaging imposes different constraints over callbacks than WS-*. Changing conversational to an intent from a service attribute helps to address this issue.  
   

On the topic of stateful proxies:
----------------------------------------------------------------
I asked about stateful proxies in the context of conversations to find out if you store a conversation handle in the proxy or somewhere else. I don't see an answer to that question (or I didn't understand your answer).

Conversation handles can be stored in a stateful proxy if the implementation is stateless. For multithreaded implementations, the handle can be stored as part of the context associated with the request in a stack-like form that is guaranteed to be visible to only one thread at a time. This will probably require verbal explanation, which I'm happy to do.


On the topic of n-party conversations:
--------------------------------------------------------------
Reading your response is an "ah ha" moment, I think. Looks like you've implemented conversations as a shared context model which is the model I would also prefer (but which is not what the specs currently describe). Now I'm confused because you seem to want to keep the current spec model, but yet what you've implemented is what I think we'd all prefer to have (if we had time to work it out).

Conversations are shared context, however, they are a shared context between a client and a provider. I suspect we may have different understandings of what shared context means. Before I comment further, could you roughly sketch out what you mean by shared context and what it would look like to use in a Java (or other) component implementation?

I also believe we have enough time to get this right before February, particularly given these features have precedents in other programming models. IMO, these are essential features and I am willing to contribute as much time as necessary to get them right.

Jim 


thanks

Dave Booz
STSM, BPM and SCA Architecture
Co-Chair OASIS SCA-Policy TC and SCA-J TC
"Distributed objects first, then world hunger"
Poughkeepsie, NY (845)-435-6093 or 8-295-6093
e-mail:booz@us.ibm.com

<graycol.gif>Jim Marino ---12/10/2008 02:19:03 PM---Hi Dave, I figured you would take me up on the offer :-) Responses inline.

<ecblank.gif>
From:
<ecblank.gif>
Jim Marino <jim.marino@gmail.com>
<ecblank.gif>
To:
<ecblank.gif>
David Booz/Poughkeepsie/IBM@IBMUS
<ecblank.gif>
Cc:
<ecblank.gif>
sca-assembly@lists.oasis-open.org
<ecblank.gif>
Date:
<ecblank.gif>
12/10/2008 02:19 PM
<ecblank.gif>
Subject:
<ecblank.gif>
Re: [sca-assembly] Fwd: Conversational services





Hi Dave,

I figured you would take me up on the offer :-) Responses inline.

Jim

On Dec 9, 2008, at 11:28 AM, David Booz wrote:
      Hi Jim,
      Thanks for the offer, I'll take you up on it. Interoperability (SCA binding aside) is quite key to the overall SCA story because the world is full of non-SCA services, so I don't think we can just cast interop aside. I think vendor extensions are perfectly acceptable. Portability is less important than interop at this point in time (I didn't say unimportant). Perhaps you disagree. I would much rather see vendors experiment with extensions that can be standardized at a later point in time. Conversations seems like a very good candidate for such a thing given all the churn we've had.
We may disagree that interop is more important than portability at this point but we should define what we mean by each term. Interop can mean many things:

1. The ability for different vendor runtimes to operate as part of the same domain. This isn't important to us as we have no desire to mix-and-match runtimes from different vendors. And if we did try, operations would have a fit :-)

2. The ability to specify binding information that will properly flow invocations using Web Services technologies from external non-SCA clients and to external non-SCA providers. This form of interop is important to us.

3. The ability to specify binding information that will support non-SCA Web Services extensions provided by other vendors. For example, support for stateful/conversational services provided by Microsoft .NET (Durable Services) and the JAX-WS RI. This is a nice-to-have but not essential.

4. Binding interop for SCA semantics. For example, the ability to flow an invocation using a binding between a client component hosted in one vendor's SCA runtime and a service provider hosted in another vendor's SCA runtime while preserving the range of SCA semantics. Again, this is a nice-to-have but isn't critical for us. Also, there are probably only a limited number of remote communications protocols which are standardized enough to make this possible.

Based on the above and our experience, there is a clear pattern and priority that has emerged for us. This may be different for other architectures. For our requirements, protocol-level interop (#2) is important for a relatively small number of services (in comparison the the total number of services in our systems) that operate at the edge of the domain. These services tend to be very loosely coupled (e.g. passing self-contained documents) as they interact with clients and providers that are beyond our control (e.g. third-party banks). Most of the time they are not async due to the added complexities of getting non-blocking patterns to work reliably across vendors. Interop type #1 we would never use due to unnecessary complexity and operational issues it raises. Type 3 is a nice to have that we could potentially use and is more important than type 4 which we probably don't have much use for. So for us, order of importance is: 2,3,4,1.

I would be interested in seeing how others building enterprise SCA applications would rank the above if they had to due so in absolute order.

While type 2 interop (web services interop) which has some relevance to us, what is extremely important is skills portability. As for application portability, it is probably fair to say given the amount of extensibility provided for by the specs, SCA applications will be much less portable than their JEE counterparts. So while application portability would be a nice feature, we don't think it will be a reality for a very long time (JEE still isn't very portable for most enterprise scenarios) and will be less than what JEE has achieved. However, skills portability is very important to us and it is something that people should be able to expect from SCA in the short-term. We want to hire developers that have a basic understanding of core SCA concepts (e.g. services, composites, components, wires, bindings) and can use that understanding to quickly come up to speed with our applications.

      Can you explain how you implemented conversations over web services, and the tradeoffs for the design decisions you made? Which pieces of WS-Addressing did you use, etc....
That's a bit of an open ended question that I could probably talk about at length :-)

It's interesting you started with web services. We actually don't view conversations over web services as a critical use case, although that may be a peculiarity of our application architectures. We only use web services for communication at the edge of the domain as we find them overly complex for what we need to do, and insufficient from a performance and reliability perspective. In other words, we only use web services for the most loosely coupled forms of interaction. The overwhelming majority of our remote intra-domain communications are via messaging ("the software formerly know as MQ Series", Oracle AQ) and to a much lesser extent, XML over HTTP. I suspect many other high-performance systems will adopt architectures similar to ours by relying heavily on messaging for remote communications inside the domain and web services for external communications.

However, we have done work integrating our conversational infrastructure with web services technologies even though it is not used in production (as our other support is). The important thing is our conversational infrastructure is a separate concern from bindings and the subsystems that support the latter. This allows for the possibility of dynamically reconfiguring bindings and providing a more flexible implementation of binding.sca. The other feature it provides is the ability to support multiple modes of propagating correlation information.

It's also interesting you started with WS-Addressing. Transport protocols are not my forte, but I've seen conversational support implemented in other systems using a variety of techniques. We have used two approaches with the idea that they are configured in applications hosted on our SCA runtime through policy. The first is by having the client "request" a GUID from our conversational infrastructure (this only involves an in-process, relatively in-expensive call) and propagate it via WS-A ReferenceParameters. This will then be included as a SOAP header on the callback. It's interesting to note the JAX-WS RI takes the same approach, as does one commercial BPEL vendor I have spoken with that has implemented engine managed correlation. For example, the following is an example of how the JAX-WS RI propagates conversational (or "stateful" as it is called) information:

<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<ns1:getProductResponse xmlns:ns1="http://server.stateful/" xmlns:ws-a="http://www.w3.org/2005/08/addressing">
<return>
<ws-a:Address>http://localhost:4040/jaxws-stateful/book</ws-a:Address>
<ws-a:ReferenceParameters>
<jaxws:objectId xmlns:jaxws="http://jax-ws.dev.java.net/xml/ns/" xmlns:wsa="http://www.w3.org/2005/08/addressing">
some opaque id
</jaxws:objectId>
</ws-a:ReferenceParameters>
</return>
</ns1:getProductResponse>
</soap:Body>
</soap:Envelope>

We do something similar although our object ID is quite different (we are using a thread-safe callstack as described below). This approach can also be used in conjunction with load-balancers to maintain "sticky" conversations in a cluster in much the same way many servlet containers work as well as support fail-over for multiple callback hops.

Another way I have seen conversations propagated is how Microsoft Durable Services work using service-provider tokens. In this model, they have decoupled the conversational model from how correlation is transmitted (in SOAP headers via WsHttpContextBinding, or using cookies via BasicContextBinding). With this approach, one issue is that the SCA infrastructure will have to wait for a back channel message containing the token before a second invocation is delivered. In the Java group, I outlined a fairly detailed sequence diagram of how this can be achieved in a thread-safe manner so I won't repeat it here. The method I outlined is not the most optimized, but I believe it demonstrates this can be done. The challenging part here is a potential race condition where a reference proxy is serialized and deserialized before the back channel message is received. There are ways, however, I think this can be avoided.
      Do you have a need to expose conversations on the "edges" of the Domain...i.e. services and references that reach outside the domain?
No. IMO people should keep those types of services as loosely coupled as possible, which means generally not using conversations. However, within a domain, where both the client and provider are under the control of a common infrastructure, we have used them extensively.
      Do you support conversations in bidirectional cases? If so, how did you deal with the remote garbage collection problems?
By bidirectional cases, do you mean conversational callbacks? If so, yes, and I think conversational callbacks are much more common that stateless callbacks. Remote garbage collection is best dealt with by a combination of:

1. Ensuring the initiating client or callback expires the conversation
2. Ensuring application components set a expiry time out (in Java, through the use of @ConversationalAttributes)
3. Providing a proprietary extension in our runtime to set default conversation timeout values.

One area that has lead to some errors is failure by developers to explicitly end a conversation in application code. However, this is mitigated by doing 2 and 3.
      Are your service proxies stateful? Do you have threading restrictions on how/when they can be de-serialized? Can the same serialized proxy be de-serialized concurrently onto two different threads? Can a composite scoped runtime instance be part of more than one conversation at a time?
Some of our service proxies are stateful and some are not. This is determined by the scope of the client component. Yes, our service proxies can be deserialized concurrently (and we support async conversations in a safe manner as well).

Yes, a composite scoped runtime instance can be part of more than one conversation at a time when we use conversational propagation (we use this pattern quite frequently). We don't have the need in our applications for a composite scoped component to act as an initiating client of a conversation but we have implemented this capability in our runtime. Actually, I generally view this pattern as a sign of a design problem in the application that can be better handled through refactoring the client to a different scope. However, there may be legitimate use-cases for this. If a composite scoped client needs to conduct two simultaneous conversations with the same service provider (I would argue this falls out of the 80% use case range), then it will need to create multiple proxies the the service. Mike R's and my proposal for simplifying the Java API we submitted a while back addresses how to do this so I won't repeat it here.

Basically, we have a model where we implement a thread-safe callstack (clone on thread-association) very similar to the way OO languages are implemented that can be used in clustered environments. I think it best to discuss details on the phone if you are interested as we will need to get into very specific implementation details. We have found this addresses a lot of the thorny issues around asynchrony.

As a side note, given the complexities associated with service reference serialization and my belief that it falls outside the "80% use case" yardstick, I would be happy to eliminate such capability that from the Java specification. That would simplify things greatly. However, it is worth noting that the JAX-WS RI does support this capability. For example:

// .....

Cart cart1 = service.getPort(cartProvider.getCart("123"), Cart.class);

W3CEndpointReference cartEpr = cartProvider.getCart("123");

ByteArrayOutputStream baos = new ByteArrayOutputStream();
cartEpr.writeTo(new StreamResult(baos));

cartEpr = new W3CEndpointReference(new StreamSource(new ByteArrayInputStream(baos.toByteArray())));

// cart1 and cart2 point to the same provider instance
Cart cart2 = service.getPort(cartEpr, Cart.class);

Microsoft .NET Durable services also support this capability, although I thought it best not to try and write C# given my lack of experience with it :-)
      With regard to n-party conversations, what is the model you're using? How are the parties notified of conversation lifecycle changes? How do they get handles to existing conversations? How do you know when a conversation is no longer valid? Does any one conversation instance have the ability to affect any other conversation?
Policy is the model we are using, i.e. our support for multi-party conversations is actually implemented as an extension to our core runtime over top of our policy extension. We have a model where multiple component instances can participate in a conversation similar to the way transaction propagation works. There is not much novel about it as I believe CORBA and other distributed systems had analogous approaches to stateful contexts.

To your question on conversation lifecycle, there is a set of container instances that manage component implementation instances. These containers coordinate across a distributed domain to manage conversation lifecycle. This is manageable if we assume conversations have three states: starting, in-progress, and end.
      There may be simple answers to the above that we've overlooked.

I'm sure I haven't sufficiently answered your questions as it is difficult to get detailed in an email. I'm happy to discuss verbally and work through these issues.

Jim


      Dave Booz
      STSM, BPM and SCA Architecture
      Co-Chair OASIS SCA-Policy TC and SCA-J TC
      "Distributed objects first, then world hunger"
      Poughkeepsie, NY (845)-435-6093 or 8-295-6093
      e-mail:
      booz@us.ibm.com

      <graycol.gif>
      Jim Marino ---12/09/2008 12:55:47 PM---Hi, I also should have mentioned that I am willing to share our
      <ecblank.gif>
      From:
      <ecblank.gif>
      Jim Marino <jim.marino@gmail.com>
      <ecblank.gif>
      To:
      <ecblank.gif>
      OASIS Assembly <sca-assembly@lists.oasis-open.org>
      <ecblank.gif>
      Date:
      <ecblank.gif>
      12/09/2008 12:55 PM
      <ecblank.gif>
      Subject:
      <ecblank.gif>
      [sca-assembly] Fwd: Conversational services




      Hi,


      I also should have mentioned that I am willing to share our experiences implementing and using conversational services in more detail if people are interested. This is an extremely important feature to us and I hope SCA continues to provide conversational capabilities.


      Jim


      Begin forwarded message:
              From: Jim Marino <jim.marino@gmail.com>
              Date:
              December 9, 2008 9:35:13 AM PST
              To:
              OASIS Assembly <sca-assembly@lists.oasis-open.org>
              Subject: Conversational services


              Hi,

              Martin mentioned Oracle's experience with conversational services led them to the conclusion that they were "half-baked" and too complex on the Assembly call today. Unfortunately, time ran out before I could ask him to elaborate. From an end-user perspective, conversations are a critical part of our applications. Without them, we will likely be forced to adopt a proprietary approach (or potentially look to another technology), which for obvious reasons we don't want to do. Based on my discussions in the past with other end-users, I don't think I am alone in my views.

              As some background, we are currently building several European inter-bank payment and ATM processing systems which are in various stages of production use. The size of these applications are quite large (over 150 composites each) and the requirements challenging, but due to SCA's ease-of-use, we were able to implement them successfully with developers who had no prior SCA exposure and relatively limited experience with service-based architectures. In building these applications, conversational services allowed us to greatly simplify many previously complex tasks, such as large document processing and managing JPA persistence contexts. From a cost and ongoing maintenance standpoint, conversational service support has allowed us to remove an enormous amount of "boilerplate" code that existed in our legacy systems.

              We were able to support conversational services in our SCA infrastructure in a relatively straightforward way. So far, based on our application throughput requirements (processing 100 million transactions in a three hour period), we have not encountered any performance issues related to conversations.

              I'm sure there are areas where they can be improved. For example, multi-party conversations is one, which we have implemented as a proprietary extension in our infrastructure. There is also the question of inter-operability, although I don't view that as necessarily important at this stage given SCA runtimes from different vendors are not likely to interoperate (e.g. different vendor runtimes participating in the same domain) any time in the near future. However, before we remove such an important feature, I would like to understand the specifics of why conversations are too complex both to use and implement. Granted, there are areas in need of further specification and refinement, but I think that can be said of many SCA features.

              Not to single people out, but Martin and Mike, you both made these claims on the call. Could you please elaborate with technical details?

              Thanks,
              Jim






[Date Prev] | [Thread Prev] | [Thread Next] | [Date Next] -- [Date Index] | [Thread Index] | [List Home]