Ignore:
Timestamp:
07/12/13 23:41:06 (11 years ago)
Author:
psniegowski
Message:

HIGHLIGHTS:

  • add <include/> to configuration
  • add side notes to tree
    • used to store arbitrary information alongside the tree structure
  • migrate to log4j2
    • supports lazy string evaluation of passed arguments
  • improve GUI tree
    • it stays in synchronization with actual state (even in high load test scenario)
  • improve panel management in GUI
  • make loading objects in GUI more lazy
  • offload parsing to connection receiver thread
    • info parsing
    • first step of objects parsing
  • fix connection parsing bug (eof in long values)
  • support zero-arguments procedure in table view

CHANGELOG:
Implement procedure calls from table view.

Refactorization around procedures in tables.

Add table editor for buttons.

Render buttons in the the list view.

Further improve Columns.

Add Column class for TableModel?.

Accept also non-arguments ProcedureParams? in tableView.

Increase maximal TextAreaControl? size.

Add tooltip to ProcedureControl?.

Fix bug of interpreting eofs in long values by connection reader.

Further rework connection parsing.

Simplify client connection processing.

Test ListChange? modification.

Test ListChange? events with java server.

Add TestChild?.

Fix bug with fast deregistering when connecting to running server.

Another minor refactorization in TreeOperations?.

Fix bug in SimpleAbstractAccess? loading routine.

Another minor improvement.

Minor change.

Make reading of List objects two-phase.

Another minor change.

Dispatch parsing into receiver thread.

Another step.

Enclose passing value in ObjectParam? case in closure.

Minor step.

Minor change on way to offload parsing.

Temporarily comment out single ValueParam? get.

It will be generalized to multi ValueParam?.

Process info in receiver thread.

Add DispatchingExceptionHandler?.

Make waits in browser test longer.

Use FETCHED_MARK.

It is honored in GUI, where it used to decide whether to get values

after user action.

It is set in standard algorithm for processing fetched values.

Add remove operation to side notes.

Make loading more lazy.

Improve loading policy.

On node choose load itself, on node expansion, load children.

Minor improvement.

Fix bug with panel interleaving.

Minor improvements.

Improve panel management.

More cleaning around panels.

Reorganize panels.

Further improve tree.

Fix bug in TreeModel?.

Remove children from TreeNode?.

Implement TreeNode? hashCode and equals.

Make TreeNode? delegate equals and hashcode to internal reference.

Move listeners from TreeNode? to side notes.

Store path.textual as a side note.

Side note params instead of accesses for objects.

More refactorizations.

In TreeNode? bindAccess based on side notes.

Minor step.

Hide createAccess.

Rename AccessInterface? to Access.

Minor changes.

Several improvements in high load scenarios.

Change semantics of ArrayListAccess?.set(index, null);

It now removes the element, making list shorter
(it was set to null before).

Add path remove handler.

Handle exceptions in Connection.

Update .gitignore

Configure logging to file.

Move registration to TreeModel?.

Further refactorization.

Minor refactorization.

Minor improvements.

Use specialized event also for Modify action of ListChange?.

Use remove events.

Use the insertion events for tree.

Further improve tree refreshing.

Further improve reacting on events in GUI.

Fix problem with not adding objects on addition list change.

Migrate to log4j lazy String construction interface.

Migrate imports to log4j2.

Drop dependency on adapter to version 1.2.

Switch log4j implementation to log4j2.

Add dirty mark to the NodeAtFrame?.

Make selecting in AccessInterfaces? type safe.

Ignore containers size settings in Model and Genotype.

Use tree side notes to remember local changes and panels.

Add sideNotes to tree.

They will be used to store various accompanying information
right in the tree.

Use ReferenceIdentityMap? from apache in TreeNode?.

It suits the need perfectly (weak semantics on both key and value).

Make ArrayListParam? do not react size changes.

Guard in TableModel? before not yet loaded objects.

Add <include/> clause and AutoInjector?.

Extract common columns configuration to separate xml,
that can be included by other configurations.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • java/main/src/main/java/com/framsticks/communication/ClientSideManagedConnection.java

    r99 r100  
    1717import com.framsticks.util.dispatching.FutureHandler;
    1818import com.framsticks.util.dispatching.JoinableState;
     19import com.framsticks.util.lang.Casting;
    1920import com.framsticks.util.lang.Pair;
    2021import com.framsticks.util.lang.Strings;
    2122import com.framsticks.params.EventListener;
    2223
    23 import org.apache.log4j.Logger;
     24import org.apache.logging.log4j.Logger;
     25import org.apache.logging.log4j.LogManager;
    2426
    2527import java.util.*;
    2628import java.util.regex.Matcher;
     29
     30import javax.annotation.Nonnull;
     31import javax.annotation.Nullable;
     32
    2733import com.framsticks.util.dispatching.RunAt;
    2834
     
    3238public class ClientSideManagedConnection extends ManagedConnection {
    3339
    34         private final static Logger log = Logger.getLogger(ClientSideManagedConnection.class);
     40        private final static Logger log = LogManager.getLogger(ClientSideManagedConnection.class);
    3541
    3642        private final List<Runnable> applicationRequestsBuffer = new LinkedList<>();
     
    6066
    6167
    62         private static abstract class InboundMessage {
    63                 protected String currentFilePath;
    64                 protected List<String> currentFileContent;
    65                 protected final List<File> files = new ArrayList<File>();
    66 
    67                 public abstract void eof();
    68 
    69                 protected void initCurrentFile(String path) {
    70                         currentFileContent = new LinkedList<String>();
    71                         currentFilePath = path;
    72                 }
    73 
    74                 protected void finishCurrentFile() {
    75                         if (currentFileContent == null) {
    76                                 return;
    77                         }
    78                         files.add(new File(currentFilePath, new ListSource(currentFileContent)));
    79                         currentFilePath = null;
    80                         currentFileContent = null;
    81                 }
    82 
    83                 public abstract void startFile(String path);
    84 
    85                 public final void addLine(String line) {
    86                         assert line != null;
    87                         assert currentFileContent != null;
    88                         currentFileContent.add(line);
    89                 }
    90 
    91                 public List<File> getFiles() {
    92                         return files;
    93                 }
    94         }
    9568
    9669        protected List<String> readFileContent() {
    9770                List<String> content = new LinkedList<String>();
    9871                String line;
    99                 while (!(line = getLine()).startsWith("eof")) {
     72                boolean longValue = false;
     73                while (true) {
     74                        line = getLine();
     75                        if (longValue) {
     76                                if (line.endsWith("~") && !line.endsWith("\\~")) {
     77                                        longValue = false;
     78                                }
     79                        } else {
     80                                if (line.equals("eof")) {
     81                                        break;
     82                                }
     83                                if (line.endsWith(":~")) {
     84                                        longValue = true;
     85                                }
     86                        }
    10087                        content.add(line);
    10188                }
     
    10390        }
    10491
    105         private static class SentQuery<C> extends InboundMessage {
     92        private static class SentQuery<C> {
     93
    10694                Request request;
    10795                ClientSideResponseFuture callback;
    10896                Dispatcher<C> dispatcher;
    109 
    110                 public void startFile(String path) {
    111                         finishCurrentFile();
    112                         if (!Strings.notEmpty(path)) {
    113                                 assert request instanceof ApplicationRequest;
    114                                 path = ((ApplicationRequest) request).getPath();
    115                         }
    116                         Strings.assureNotEmpty(path);
    117                         initCurrentFile(path);
    118                 }
    119 
    120                 public void eof() {
    121                         assert Strings.notEmpty(currentFilePath);
    122                         finishCurrentFile();
    123                         //no-operation
     97                protected final List<File> files = new ArrayList<File>();
     98
     99                public List<File> getFiles() {
     100                        return files;
    124101                }
    125102
     
    169146
    170147                if (getState().ordinal() > JoinableState.RUNNING.ordinal()) {
    171                         log.fatal("not connected");
    172                         return;
     148                        throw new FramsticksException().msg("connection is not connected").arg("connection", this);
    173149                }
    174150
     
    211187                                putLine(out);
    212188                                flushOut();
    213                                 log.debug("sending query: " + out);
     189                                log.debug("sending query: {}", out);
    214190
    215191                        }
     
    217193                /*
    218194                synchronized (this) {
    219                         log.debug("queueing query: " + query);
     195                        log.debug("queueing query: {}", query);
    220196                        queryQueue.offer(sentQuery);
    221197                        notifyAll();
     
    253229        }
    254230
    255         private synchronized SentQuery<?> fetchQuery(Integer id, boolean remove) {
    256                 if (id == null) {
    257                         if (requestIdEnabled) {
    258                                 return null;
    259                         }
    260                         SentQuery<?> result = currentlySentQuery;
    261                         if (remove) {
    262                                 currentlySentQuery = null;
    263                                 notifyAll();
    264                         }
    265                         return result;
    266                 }
    267                 if (queryMap.containsKey(id)) {
     231        private synchronized @Nonnull SentQuery<?> fetchQuery(@Nullable Integer id, boolean remove) {
     232                try {
     233                        if (id == null) {
     234                                if (requestIdEnabled) {
     235                                        throw new FramsticksException().msg("request_id is enabled and id is missing");
     236                                }
     237                                SentQuery<?> result = currentlySentQuery;
     238                                if (remove) {
     239                                        currentlySentQuery = null;
     240                                        notifyAll();
     241                                }
     242                                return result;
     243                        }
     244
     245                        if (!queryMap.containsKey(id)) {
     246                                throw new FramsticksException().msg("id is unknown").arg("id", id);
     247                        }
     248
    268249                        SentQuery<?> result = queryMap.get(id);
    269250                        if (remove) {
     
    271252                        }
    272253                        return result;
    273                 }
    274                 return null;
     254
     255                } catch (FramsticksException e) {
     256                        throw new FramsticksException().msg("failed to match response to sent query").cause(e);
     257                }
    275258        }
    276259
    277260        private int nextQueryId = 0;
    278 
    279         protected void processMessage(InboundMessage inboundMessage) {
    280                 if (inboundMessage == null) {
    281                         log.error("failed to use any inbound message");
    282                         return;
    283                 }
    284 
    285                 String line;
    286                 while (!(line = getLine()).startsWith("eof")) {
    287                         // log.debug("line: " + line);
    288                         inboundMessage.addLine(line);
    289                 }
    290                 inboundMessage.eof();
    291         }
    292261
    293262        protected void processEvent(String rest) {
     
    303272                String eventCalleePath = Request.takeGroup(rest, matcher, 2).toString();
    304273                final File file = new File("", new ListSource(readFileContent()));
    305                 log.debug("firing event " + eventObjectPath);
     274                log.debug("firing event {}", eventObjectPath);
    306275                EventListener<File> listener;
    307276                synchronized (registeredListeners) {
     
    314283        }
    315284
    316         protected void processMessageStartingWith(String line) {
     285        protected void processFile(Pair<Integer, CharSequence> rest) {
     286                final SentQuery<?> sentQuery = fetchQuery(rest.first, false);
     287
     288                String currentFilePath = rest.second.toString();
     289                if (!Strings.notEmpty(currentFilePath)) {
     290                        currentFilePath = Casting.throwCast(ApplicationRequest.class, sentQuery.request).getPath();
     291                }
     292
     293                sentQuery.files.add(new File(currentFilePath, new ListSource(readFileContent())));
     294
     295        }
     296
     297        protected void processMessageStartingWith(final String header) {
    317298                try {
    318                         Pair<CharSequence, CharSequence> command = Request.takeIdentifier(line);
    319                         if (command.first.equals("event")) {
     299                        final Pair<CharSequence, CharSequence> command = Request.takeIdentifier(header);
     300                        if (command == null) {
     301                                throw new FramsticksException().msg("failed to parse command");
     302                        }
     303                        final CharSequence keyword = command.first;
     304                        if (keyword.equals("event")) {
    320305                                processEvent(command.second.toString());
    321306                                return;
    322307                        }
    323                         Pair<Integer, CharSequence> rest = takeRequestId(command.second);
    324 
    325                         if (command.first.equals("file")) {
    326                                 SentQuery<?> sentQuery = fetchQuery(rest.first, false);
    327                                 sentQuery.startFile(rest.second.toString());
    328                                 processMessage(sentQuery);
     308
     309                        final Pair<Integer, CharSequence> rest = takeRequestId(command.second);
     310                        if (rest == null) {
     311                                throw new FramsticksException().msg("failed to parse optional id and remainder");
     312                        }
     313
     314                        if (keyword.equals("file")) {
     315                                processFile(rest);
    329316                                return;
    330317                        }
    331 
    332                         SentQuery<?> sentQuery = fetchQuery(rest.first, true);
    333                         if (sentQuery == null) {
     318                        if (keyword.equals("ok") || keyword.equals("error")) {
     319
     320                                final SentQuery<?> sentQuery = fetchQuery(rest.first, true);
     321
     322                                log.debug("parsing response for request {}", sentQuery);
     323
     324                                sentQuery.dispatchResponseProcess(new Response(command.first.equals("ok"), rest.second.toString(), sentQuery.getFiles()));
    334325                                return;
    335326                        }
    336                         log.debug("parsing response for request " + sentQuery);
    337 
    338                         sentQuery.dispatchResponseProcess(new Response(command.first.equals("ok"), rest.second.toString(), sentQuery.getFiles()));
     327
     328                        throw new FramsticksException().msg("unknown command keyword").arg("keyword", keyword);
    339329                } catch (FramsticksException e) {
    340                         throw new FramsticksException().msg("failed to process message").arg("starting with line", line).cause(e);
     330                        throw new FramsticksException().msg("failed to process message").arg("starting with line", header).cause(e);
    341331                }
    342332        }
Note: See TracChangeset for help on using the changeset viewer.